由两个字段和只读字段组成的独特的_

2024-06-02 09:03:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我有此代码用于评级课程,用户和课程应自动从请求授权和URL添加:

#views.py

class RatingViewSet(
    mixins.ListModelMixin,
    mixins.CreateModelMixin,
    viewsets.GenericViewSet
):
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = RatingSerializer

    def perform_create(self, serializer):
        lessonInstance = Lesson.objects.get(id = self.kwargs['lessonID'])
        serializer.save(user=self.request.user, lesson = lessonInstance)
    def get_queryset(self):
        lessonID = self.kwargs['lessonID']
        return Rating.objects.filter(user=self.request.user, lesson=lessonID)

#serializers.py

^{pr2}$

#models.py

class Rating(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    lesson = models.ForeignKey('lessons.Lesson')
    difficulty = models.IntegerField()
    class meta:
        unique_together('user','lesson')

我希望每个用户/课程最多有1个等级,因此unique_together('user','lesson')。但是有一个问题:只要代码中有这个约束,没有userlesson字段的请求就会被拒绝,并出现field required错误,即使它们是read_only。在

(如果我使用unique_together('user','lesson')进行迁移,那么删除它可以工作的那一行,但是一到那里我就得到错误。)

我希望保留这段代码,这样就不会在以后的迁移中意外地删除unique_together约束。在


Tags: 代码用户pyselfmodelsdefmixinsclass
2条回答

这是一个需要不同方法的特殊情况。以下是django-rest-frameworkdocumentation(见注释)对这个案例的描述:

The right way to deal with this is to specify the field explicitly on the serializer, providing both the read_only=True and default=… keyword arguments.

在您的例子中,您需要显式地定义user和{}字段,如下所示:

class RatingSerializer(serializers.ModelSerializer):
    user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())  # gets the user from request
    lesson = serializers.PrimaryKeyRelatedField(read_only=True, default=None)  # or any other appropriate value

    class Meta:
        model = Rating
        fields = ('id', 'lesson','user', 'difficulty')

祝你好运!在

如果一个字段是read_only=True,那么validated_data将忽略它的数据=>;因为error required field,请在doc阅读更多内容

我也遇到了类似的问题,然后尝试了@iulian上面的答案,但没有成功! 不再支持此组合read_only+default行为,请选中this

我通过两种解决方案解决了这个问题:

  • 我的型号:
class Friendship(TimeStampedModel):
    """Model present Friendship request"""
    from_user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='friendship_from_user')
    to_user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='friendship_to_user')

    class Meta:
        unique_together = ('from_user', 'to_user')

解决方案1。编写自己的CurrentUserDefault类以获取用户id,然后将其设置为序列化程序的默认属性数据(Ref from #51940976

^{pr2}$

解决方案2。重写序列化程序的create方法以设置用户id的数据(Ref fromthis

class FriendshipSerializer(serializers.ModelSerializer):
    class Meta:
        model = Friendship
        fields = ('id', 'from_user', 'to_user', 'status')
        extra_kwargs = {
            'from_user': {'read_only': True},
        }


    def create(self, validated_data):
        """Override create to provide a user via request.user by default.

        This is require since the read_only `user` filed is not included by default anymore since
        https://github.com/encode/django-rest-framework/pull/5886.
        """
        if 'user' not in validated_data:
            validated_data['from_user'] = self.context['request'].user

        return super(FriendshipSerializer, self).create(validated_data)

我希望这有帮助!在

相关问题 更多 >