【问题标题】:Include foreign key in saving Django-Rest-Framework serializer在保存 Django-Rest-Framework 序列化程序时包含外键
【发布时间】:2021-04-09 13:33:32
【问题描述】:

我正在使用 Django Rest Framework 创建一个 API。您可以给 api 一个术语,它在第三方 API 上查找数据,然后所有内容都应存储到数据库中。 一切都在用户范围内处理,我有两个表,一个包含搜索词和用户 ID,另一个包含接收到的数据,其中 search_id 作为外键。 我现在想要的是,如果您向 API 发送一个术语,所有内容都会被存储,并且您会返回搜索结果,包括 ID 和所有日期。到目前为止,一切都很好。我现在卡住了,我需要将第三方数据保存到数据库中。 序列化器在保存时需要模型对象,而不是来自用户输入的序列化器。我试过了,但不知道我做错了什么:

models.py:

class Search(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             on_delete=models.CASCADE,)
    term = models.CharField(max_length=200)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.term


class foundTables(models.Model):
    search = models.ForeignKey(Search,
                               related_name='search',
                               on_delete=models.CASCADE)
    code = models.CharField(max_length=200)
    content = models.CharField(max_length=1000)
    time = models.CharField(max_length=200, blank=True, default='')
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.content

序列化器.py

class SearchSerializer(serializers.ModelSerializer):
    class Meta:
        model = Search
        fields = ['id', 'user', 'term', 'created', 'updated']
        read_only_fields = ['id', 'user', 'created', 'updated']


class foundTablesSerializer(serializers.ModelSerializer):
    search = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = foundTables
        fields = [
            'id',
            'search',
            'code',
            'content',
            'time',
            'created',
            'updated']
        read_only_fields = [
            'id',
            'search',
            'created',
            'updated']

views.py

class genesisRequestViewSet(viewsets.ModelViewSet):
    queryset = Search.objects.all()
    serializer_class = SearchSerializer
    permission_classes = [permissions.IsAuthenticated]
    http_method_names = ['get', 'post']

    def get_queryset(self):
        user = self.request.user
        return Search.objects.filter(user=user).order_by('-created')[:1]

    def create(self, request):
        user = self.request.user
        term = request.data['term']
        seria = SearchSerializer(data=self.request.data)
        genesis = findRequest()
        if seria.is_valid():
            # search = Search(user=user, term=term)
            # search.save()
            seria.save(user=user)
            genesis.get(term=term)
            if genesis.data['Tables']:
                genesisdict = {}
                for element in genesis.data['Tables']:
                    genesisdict['code'] = element['Code']
                    genesisdict['content'] = element['Content']
                    genesisdict['time'] = element['Time']
                    tables = foundTablesSerializer(data=genesisdict)
                    if tables.is_valid():
                        tables.save(search=seria)
                    else:
                        return Response(tables.errors)
                return Response(seria.data)
            else:
                return Response({"status": "No tables found"})
        else:
            return Response({"errors": seria.errors})

所以,如果我使用静音的“search=Search...”方法,它会起作用,但我当然想使用序列化程序。

save 方法返回一个错误,它需要一个 Search 实例:

ValueError at /api/genesis/
Cannot assign "SearchSerializer(data={'term': 'testterm'}):
    id = IntegerField(label='ID', read_only=True)
    user = PrimaryKeyRelatedField(read_only=True)
    term = CharField(max_length=200)
    created = DateTimeField(read_only=True)
    updated = DateTimeField(read_only=True)": "foundTables.search" must be a "Search" instance.

任何想法,我如何在表序列化程序中获取外键?

【问题讨论】:

    标签: django serialization django-rest-framework


    【解决方案1】:

    我不知道我是否理解您的问题,但 serializer.save() 返回一个实例,您可以像这样更改您的代码:

    从 save() 方法中获取您的 Search 实例:

    search_ins = seria.save(user=user)
    

    并像这样在foundTablesSerializer 中使用:

    tables.save(search=search_ins)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-19
      • 2021-06-22
      • 2016-04-10
      • 2013-06-21
      • 2018-06-07
      • 1970-01-01
      • 2018-06-23
      相关资源
      最近更新 更多