我想在DRF中包含一个GenericRelation
反向的模型
文档表明这应该很简单(就在上面:http://www.django-rest-framework.org/api-guide/relations/#manytomanyfields-with-a-through-model) - 但我遗漏了一些东西!
请注意反向通用键,使用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' object has no attribute 'pk'
和第二个
<django.contrib.contenttypes.fields.create_generic_related_manager.<locals>.GenericRelatedObjectManager object at 0x7f7f3756cf60> is not JSON serializable
所以,显然我误解了什么,不知道是什么?
答案 0 :(得分:2)
嗯,我有一个有效的解决方案,虽然它不像是正确的解决方案......
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',)
url
VoteableSerializer
VoteableSerializer
ModelSerializer
至HyperlinkedModelSerializer
VoteableRelatedField
并从查询集中获取第一项(特别是这感觉不对)我还没有将此标记为已被接受,希望有人可以告诉我应该如何
完成!答案 1 :(得分:2)
解决方案的另类想法,似乎更适合GenericRelation ......
优点:
这意味着投票信息始终在相关对象上,简化了排序和排序。查询并避免加入。
缺点:
投票需要更多的空间
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')
也许更优化,但更少的干将是单独的&#34;投票&#34;继承Voteable
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')
答案 2 :(得分:1)
doc有一个自定义相关的序列化程序字段似乎是GenericRelation的脚注:
请注意反向通用键,使用GenericRelation表示 字段,可以使用常规关系字段类型序列化, 因为关系中目标的类型总是已知的。
以下申请。同时检查this DRF3扩展名。
class QuestionSerializer(serializers.HyperlinkedModelSerializer):
voteable = VoteableSerializer(read_only=True)
class Meta:
model = Question
fields = ('url', 'question', 'user', 'voteable')
...