Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将GenericRelation与Django Rest框架一起使用?_Python_Django_Serialization_Django Rest Framework_Generic Relations - Fatal编程技术网

Python 如何将GenericRelation与Django Rest框架一起使用?

Python 如何将GenericRelation与Django Rest框架一起使用?,python,django,serialization,django-rest-framework,generic-relations,Python,Django,Serialization,Django Rest Framework,Generic Relations,我想在DRF中包含一个具有一般关系反向引用的模型 文档表明这应该很容易(就在上面:)-但我遗漏了一些东西 请注意,使用GenericRelation表示的反向通用键 字段,可以使用常规关系字段类型序列化, 因为关系中的目标类型总是已知的 有关更多信息,请参阅关于泛型的Django文档 关系 我的模型: class Voteable(models.Model): content_type = models.ForeignKey(ContentType, on_delete=models.C

我想在DRF中包含一个具有
一般关系
反向引用的模型

文档表明这应该很容易(就在上面:)-但我遗漏了一些东西

请注意,使用GenericRelation表示的反向通用键 字段,可以使用常规关系字段类型序列化, 因为关系中的目标类型总是已知的

有关更多信息,请参阅关于泛型的Django文档 关系

我的模型:

class Voteable(models.Model):
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    direct_vote_count = models.IntegerField(default=0)

class Question(models.Model):
    user = models.ForeignKey(UserExtra, related_name='questions_asked')
    voteable = GenericRelation(Voteable)
    question = models.CharField(max_length=200)
和我的序列化程序:

class VoteableSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Voteable
        fields = ('pk', 'id', 'url', 'direct_vote_count')


class QuestionSerializer(serializers.HyperlinkedModelSerializer):
    #voteable = VoteableSerializer(read_only=True, many=False)
    #voteable = serializers.PrimaryKeyRelatedField(many=False, read_only=True)

    class Meta:
        depth = 1
        model = Question
        fields = ('url', 'question', 'user', 'voteable')
注释掉的两行是我试图告诉DRF如何序列化
voteable
内部
Question

第一个给了我

“GenericRelatedObjectManager”对象没有属性“pk”

第二个呢

不是JSON可序列化的

class Voteable(models.Model):
    direct_vote_count = models.IntegerField(default=0)

    class Meta:
        abstract = True

class Question(Voteable):
    user = models.ForeignKey(UserExtra, related_name='questions_asked')
    question = models.CharField(max_length=200)

class QuestionVote(models.Model):#This class also repeated for each item that can be voted on
    user = models.ForeignKey(UserExtra, related_name='questions_asked')
    parent = models.ForeignKey(Question, related_name='votes')

所以,很明显我误解了什么,知道什么吗?

好吧,我有一个有效的解决方案,尽管它感觉不是正确的解决方案

class VoteableSerializer(serializers.ModelSerializer):
    class Meta:
        model = Voteable
        fields = ('pk', 'direct_vote_count')


class VoteableRelatedField(serializers.RelatedField):
    def to_representation(self, value):
        serializer = VoteableSerializer(value.get_queryset()[0])
        return serializer.data

class QuestionSerializer(serializers.HyperlinkedModelSerializer):
    #voteable = VoteableSerializer(read_only=True, many=False)
    #voteable = serializers.PrimaryKeyRelatedField(many=False, read_only=True)

    voteable = VoteableRelatedField(read_only=True)

    class Meta:
        depth = 1
        model = Question
        fields = ('url', 'question', 'user', 'voteable')
        read_only_fields = ('voteable',)
  • VoteableSerializer
  • VoteableSerializer
    更改为
    ModelSerializer
    HyperlinkedModelSerializer
  • 添加
    VoteableRelatedField
    并从queryset中获取第一项(这感觉特别错误)

我不会把这个标记为已被接受,希望有人能启发我如何去做

解决方案的备选方案,似乎更符合一般关系

  • 使Voteable成为一个抽象模型
  • 使用GenericForeignKey更改投票类(本问题中未显示)以指向任何对象
优点:
这意味着投票信息在相关对象上总是正确的,从而简化排序和查询并避免连接

缺点:
投票将占用更多的空间

class Voteable(models.Model):
    votes = GenericRelation(Vote)
    direct_vote_count = models.IntegerField(default=0)

    class Meta:
        abstract = True

class Question(Voteable):
    user = models.ForeignKey(UserExtra, related_name='questions_asked')
    question = models.CharField(max_length=200)

class Vote(models.Model):
    user = models.ForeignKey(UserExtra, related_name='questions_asked')
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

可能更为优化,但不那么枯燥的是,对于继承的每种类型的对象,都有一个单独的“投票”类

class Voteable(models.Model):
    direct_vote_count = models.IntegerField(default=0)

    class Meta:
        abstract = True

class Question(Voteable):
    user = models.ForeignKey(UserExtra, related_name='questions_asked')
    question = models.CharField(max_length=200)

class QuestionVote(models.Model):#This class also repeated for each item that can be voted on
    user = models.ForeignKey(UserExtra, related_name='questions_asked')
    parent = models.ForeignKey(Question, related_name='votes')

与自定义相关的序列化程序字段对于具有以下脚注的GenericRelation来说似乎是不必要的:

请注意,使用GenericRelation表示的反向通用键 字段,可以使用常规关系字段类型序列化, 因为关系中的目标类型总是已知的

应用程序如下。同时检查DRF3扩展

class QuestionSerializer(serializers.HyperlinkedModelSerializer):
    voteable = VoteableSerializer(read_only=True)

    class Meta:
        model = Question
        fields = ('url', 'question', 'user', 'voteable')
        ...

您想要实现的是通用的1对1关系。不支持开箱即用。查看可能的解决方法:
voteable=generirelation(voteable)
变为模型级别上的
voteables=generirelation(voteable)
+
voteable
属性。用这种方法,你的第一个选择应该很好。我明白了——我想我的另一个选择是使用一个有问题的常规外键(以及我想投票的其他类)指向Voteable,而不是一般的关联……将其标记为已接受——因为这似乎是问题标题的正确答案。不过,我的另一个答案可能是针对所描述的确切情况的更好的解决方案。这一部分,
value.get\u queryset()[0]
正是我所需要的,但我同意这不是最好的解决方案。很高兴听到我的帮助!在我的项目中,我实际上没有在情况中使用泛型关系,除非它们是重要的,因为许多查询很难通过这种关系运行。当然,我有一组新的问题-图形化的数据库看起来越来越诱人…我不再从事这个项目-但看看你的答案。。我引用了你引用的那句话,甚至尝试了你建议的解决方案!(many=false)但是,您链接到的扩展可能很好地完成了所需的工作-而且可能DRF已经修复了使我们的两个代码都能工作的问题-不幸的是,我无法测试