python - DRF : how to change the value of the model fields before saving to the database

标签 python django django-rest-framework

如果我需要在保存到数据库之前更改某些字段值,因为我认为模型方法 clear() 是合适的。但尽管我竭尽全力,还是无法调用它。

例如,字段email我需要设置为小写,字段nda我需要设置为null

models.py

class Vendors(models.Model):

    nda = models.DateField(blank=True, null=True)
    parent = models.OneToOneField('Vendors', models.DO_NOTHING, blank=True, null=True)

    def clean(self):
        if self.nda == "":
            self.nda = None

class VendorContacts(models.Model):
    ....
    vendor = models.ForeignKey('Vendors', related_name='contacts', on_delete=models.CASCADE)
    email = models.CharField(max_length=80, blank=True, null=True, unique=True)

    def clean(self):
        if self.email:
            self.email = self.email.lower()

序列化器.py

class VendorContactSerializer(serializers.ModelSerializer):
    class Meta:
        model = VendorContacts
        fields = (
                  ...
                  'email',)

class VendorsSerializer(serializers.ModelSerializer):
    contacts = VendorContactSerializer(many=True)

    class Meta:
        model = Vendors
        fields = (...
                  'nda',
                  'contacts',
                  )

    def create(self, validated_data):
        contact_data = validated_data.pop('contacts')
        vendor = Vendors.objects.create(**validated_data)
        for data in contact_data:
            VendorContacts.objects.create(vendor=vendor, **data)

        return vendor

views.py

class VendorsCreateView(APIView):
    """Create new vendor instances from form"""
    permission_classes = (permissions.AllowAny,)
    serializer_class = VendorsSerializer

    def post(self, request, *args, **kwargs):
        serializer = VendorsSerializer(data=request.data)
        try:
            serializer.is_valid(raise_exception=True)
            serializer.save()
        except ValidationError:
            return Response({"errors": (serializer.errors,)},
                            status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response(request.data, status=status.HTTP_200_OK)

正如我从文档中了解到的

Django Rest Framework serializers do not call the Model.clean when validating model serializers

在处理这个问题时,我找到了两种方法来解决。 1. 在序列化器中使用自定义方法。对于我的情况,它看起来像

类 VendorsSerializer(serializers.ModelSerializer): 联系人 = VendorContactSerializer(many=True)

class Meta:
    model = Vendors
    fields = (...
              'nda',
              'contacts',
              )

def create(self, validated_data):
    contact_data = validated_data.pop('contacts')
    vendor = Vendors.objects.create(**validated_data)
    for data in contact_data:
        VendorContacts.objects.create(vendor=vendor, **data)

    return vendor

def validate(self, attrs):
    instance = Vendors(**attrs)
    instance.clean()
    return attrs
  • 使用full_clean()方法。对我来说,它看起来像
  • 类 VendorsSerializer(serializers.ModelSerializer): 联系人 = VendorContactSerializer(many=True)

    class Meta:
        model = Vendors
        fields = (...
                  'nda',
                  'contacts',
                  )
    
    def create(self, validated_data):
        contact_data = validated_data.pop('contacts')
        vendor = Vendors(**validated_data)
        vendor.full_clean()
        vendor.save()
        for data in contact_data:
            VendorContacts.objects.create(vendor=vendor, **data)
    
        return vendor
    

    但是在这两种情况下,都不会调用 clean() 方法。我真的不明白我做错了什么。

    最佳答案

    就我而言,我遇到了同样的问题,但具有验证功能 我使用了下面的方法,它对我有用(不排除上面找到的方法):

    class CustomViewClass(APIView):
    
        def post(self, request, format=None):
            
            prepared_data_variable = 'some data in needed format'
            serializer = CustomSerializer(data=request.data)
        
            if serializer.is_valid(self):
                serializer.validated_data['field_name'] = prepared_data_variable
                serializer.save()
                return Response(data=serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    

    此字符串是我的解决方案的关键serializer.validated_data['field_name'] = prepared_data_variable

    关于python - DRF : how to change the value of the model fields before saving to the database,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60635118/

    相关文章:

    python - 导入错误 : No module named sitemaps

    python - Discord 丰富的嵌入按钮

    python - 尝试在应用程序之间使用 pyserial,但我得到了终端

    python - Azure AD B2C 在 id_token 之前使用 "#"进行重定向

    django - 如何将参数传递给 Django 中的 get_queryset

    django - 如何使用 Django Rest Framework 为 API View 设置自定义表单

    python - 需要 Django 权限

    python - 使用 python 将 bibtex 文件转换为 html(也许是 pybtex?)

    python - 通过 Web 界面点击并运行 docker 镜像(或 VM)?

    django - 如何将 Django 应用程序部署到 (AWS) 域名?