【问题标题】:How to create a created_by field in django rest framework model?如何在 django rest 框架模型中创建 created_by 字段?
【发布时间】:2016-06-09 01:52:11
【问题描述】:

我想在 django rest 框架模型中创建一个 created_by 字段。

它应该包含当前登录用户的user_id,并且它应该是我不需要在JSON格式的POST请求期间发送它,它应该来自请求本身,我如何使用django rest框架序列化程序来实现它。

models.py 文件:

class Company(models.Model):
    """Company model for information about company."""

    created_by = models.ForeignKey(User, null= True, blank= True, on_delete=models.CASCADE)
    company_name = models.CharField(max_length=100)

serializers.py 文件:

class CompanySerializer(serializers.ModelSerializer):
"""Serializer for companies."""

    class Meta:
        model = Company
        fields = ('id', 'created_by', 'company_name')

v1.py 文件:

class CompanyList(APIView):
"""Get and post companies data."""

    def get(self, request, format=None):
        """Get companies data.."""
        companies = Company.objects.all()
        serialized_companies = CompanySerializer(companies, many=True)
        return Response(serialized_companies.data)

    def post(self, request, format=None):
        """Post companies data."""
        serializer = CompanySerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

【问题讨论】:

    标签: django python-2.7 django-models django-rest-framework django-serializer


    【解决方案1】:

    方法一:使用CurrentUserDefault()选项

    您可以将created_by 字段中的default 参数作为serializers.CurrentUserDefault() 传递,这会将其值设置为当前用户。

    class CompanySerializer(serializers.ModelSerializer):
    """Serializer for companies."""
    
        class Meta:
            model = Company
            fields = ('id', 'created_by', 'company_name')
            extra_kwargs = {'created_by': {'default': serializers.CurrentUserDefault()}}
    

    方法二:在serializer.save()中传递user

    您可以将字段created_by 设置为read_only,然后将request.user 传递给serializer.save()

    serializers.py

    class CompanySerializer(serializers.ModelSerializer):
    """Serializer for companies."""
    
        class Meta:
            model = Company
            fields = ('id', 'created_by', 'company_name')
            extra_kwargs = {'created_by': {'read_only':True}}
    

    v1.py

    class CompanyList(APIView):
    """Get and post companies data."""
    
        def post(self, request, format=None):
            """Post companies data."""
            serializer = CompanySerializer(data=request.data)
            if serializer.is_valid():
                serializer.save(created_by=request.user) # pass current user
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    

    【讨论】:

      【解决方案2】:

      您可以将serializers.CurrentUserDefault() 用作CompanySerializercreated_by 字段的默认值,并将该字段设为read_only=True

      请参阅文档here

      【讨论】:

      • 不知何故无法正常工作。它给出了 IntegrityError: Column 'created_by_id' cannot be null。如果我离开 read_only=True,它可以工作。但是我也可以将其设置为其他内容,例如另一个用户...
      • @gabn88 同意,我也看到了这一点。 Rahul Gupta 的两种方法都对我有用。这个没有。
      • 它真的很优雅,但对我也不起作用,我得到同样的错误django.db.utils.IntegrityError: null value in column "created_by_id" violates not-null constraint
      【解决方案3】:

      试试这个解决方案

      models.py 文件

      class Student(models.Model):
          middel_name = models.CharField(max_length=100)
          user = models.OneToOneField(User)
      

      这是我的序列化程序文件

      class GetStudentUserSerializer(serializers.ModelSerializer):
          class Meta:
              model = User
              fields = ('id','username', 'email', 'first_name', 'last_name')
      
      class GetStudentSerializer(serializers.ModelSerializer):
          user = GetStudentUserSerializer('user.username')
          class Meta:
              model = Student
              fields = ('id','middel_name','user')
              depth = 1
      
          def create(self, validated_data):
              print "hello"
              student_data = validated_data.pop('student', None)
              user = super(GetStudentSerializer, self).create(validated_data)
              self.create_or_update_student(user, student_data)
              return user
      
          def update(self, instance, validated_data):
              student_data = validated_data.pop('student', None)
              self.create_or_update_student(instance, student_data)
              return super(GetStudentSerializer, self).update(instance, student_data)
      
          def create_or_update_student(self, user, student_data):
              student, created = Student.objects.get_or_create(user=user, defaults=student_data)
              if not created and student_data is not None:
              super(GetStudentSerializer, self).update(instance, student_data)
      

      【讨论】:

        猜你喜欢
        • 2015-01-17
        • 2021-10-05
        • 2013-04-26
        • 2014-05-03
        • 1970-01-01
        • 2019-11-10
        • 2017-10-22
        • 2017-06-04
        • 1970-01-01
        相关资源
        最近更新 更多