【问题标题】:Django Rest Framework: foreign key field is required in viewset or serializerDjango Rest Framework:视图集或序列化程序中需要外键字段
【发布时间】:2020-11-26 05:24:40
【问题描述】:

我对@9​​87654325@ 很陌生。我读过viewsets 非常好,因为它减少了代码量,但我发现它更复杂。

说明: 想象一下,我想实现一个电话簿 API,其中我们有一些用户,每个用户都有自己的联系人,每个联系人可以有多个电话号码。所以,我这里有三个模型。

  1. 用户(默认 Django 模型)
  2. 联系方式
class Contact(models.Model):
    owner = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='contacts'
    )
    name = models.CharField(
        max_length=70
    )
    description = models.TextField()

  1. 电话号码
class Phones(models.Model):
    person = models.ForeignKey(
        Contact,
        related_name="phones",
        on_delete=models.CASCADE,
    )

    phone_no = models.CharField(
        max_length=11,
    )

问题定义 我想要的是创建与当前request.user 的新联系人。所以我应该有我的contact.serializers,如下所示:

class ContactSerializer(serializers.ModelSerializer):
    owner = serializers.SlugRelatedField(queryset=User.objects.all(), slug_field='user')


    class Meta:
        model = Contact
        fields = ['id', 'owner', 'name', 'description']
        read_only_fields = ['owner']

我的看法是这样的:


class ContactViewSet(viewsets.ModelViewSet):
    queryset = Contact.objects.all()
    serializer_class = ContactSerializer
    permission_classes = [IsCreator]

    def get_permissions(self):
        if self.request.method == "GET":
            self.permission_classes = [IsCreator, permissions.IsAdminUser,]

        if self.request.method == "POST":
            self.permission_classes = [permissions.IsAuthenticated,]

        if self.request.method == "PUT":
            self.permission_classes = [IsCreator]

        if self.request.method == "DELETE":
            self.permission_classes = []

        return super(ContactViewSet, self).get_permissions()

错误 每当我想使用postman 发布新联系人时,我已经传递了namedescriptionowner,它应该会自动从请求中检测到所有者,但是它没有,我收到以下错误:

PS:如果需要签出这里的项目是my project link

我该怎么办?

【问题讨论】:

  • it should automatically detects the owner from the request 我没有看到任何代码这样做?
  • @Alvi15 你能给我一个答案吗?我真的需要你的帮助。
  • 查看相关链接,看看是否有效。
  • @Alvi15 我遇到了一个新错误

标签: django django-rest-framework django-serializer django-rest-viewsets


【解决方案1】:

应用以下更改后问题已解决。

apps.contacts.views.py

将以下方法添加到类的主体中

def perform_create(self, serializer):
    return serializer.save(owner = self.request.user)

apps.contacts.serializers.py

class ContactSerializer(serializers.ModelSerializer):
    class Meta:
        model = Contact
        fields = ['id', 'name', 'description', 'owner']

PS我也在寻找更多答案,在这种情况下添加您的答案。

【讨论】:

    【解决方案2】:

    您可以做的一件事是添加 currentuserdefault。像这样

    class ContactSerializer(serializers.ModelSerializer):
        owner = serializers.HiddenField(default=serializers.CurrentUserDefault())
    
        class Meta:
            model = Contact
            fields = ['id', 'owner', 'name', 'description']
    

    并且在您的视图代码中,请记住在上下文中传递请求。像这样

    class ContactViewSet(viewsets.ModelViewSet):
        queryset = Contact.objects.all()
        serializer_class = ContactSerializer
        permission_classes = [IsCreator]
    
        def get_serializer_context(self):
            context = super().get_serializer_context()
            context.update({"request": self.request})
            return context
    

    【讨论】:

    • TypeError: Field 'id' expected a number but got HiddenField(default=CurrentUserDefault()). 刚刚出现这个错误。
    • 我已经安装了您的应用程序,并按照我的建议进行了上述更改并且工作正常。但有一件事请确保在contactviewsets中删除这个def perform_create(self, serializer): return serializer.save(owner=self.request.user)
    猜你喜欢
    • 1970-01-01
    • 2016-04-10
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    • 1970-01-01
    • 1970-01-01
    • 2013-06-21
    相关资源
    最近更新 更多