我正在建立一个事件模型,有点类似于package。它具有一个 Actor ,动词和目标。
class Activity(models.Model):
actor_type = models.ForeignKey(ContentType, related_name='actor_type_activities')
actor_id = models.PositiveIntegerField()
actor = GenericForeignKey('actor_type', 'actor_id')
verb = models.CharField(max_length=10)
target_type = models.ForeignKey(ContentType, related_name='target_type_activities')
target_id = models.PositiveIntegerField()
target = GenericForeignKey('target_type', 'target_id')
pub_date = models.DateTimeField(default=timezone.now)
现在,无论何时创建任何模型(投标,工作和新闻)的新对象,都会创建一个新的Activity对象,其中
target
是这三个模型中任何一个的对象。eg. user (actor) published (verb) title (target)
class Tender(models.Model):
title = models.CharField(max_length=256)
description = models.TextField()
class Job(models.Model):
title = models.CharField(max_length=256)
qualification = models.CharField(max_length=256)
class News(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
title = models.CharField(max_length=150)
为了获取此数据,我正在制作一个API,它将获取所需的json数据。我为此使用django-rest-framework,并且它非常新。
class ActorSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'email')
class ActivitySerializer(serializers.HyperlinkedModelSerializer):
actor = ActorSerializer()
class Meta:
model = Activity
fields = ('url', 'actor', 'verb', 'pub_date')
在上面的序列化程序中,我知道
actor
将成为User。因此,我将User模型用于ActorSerializer
类。但是对于target
,它可以是这三种模型(新闻/作业/投标)中的任何一种。如何为ContentType对象创建序列化程序(例如
TargetSerialier
类),以便可以在target
类字段中使用ActivitySerializer
?
最佳答案
好吧,在这里回答我自己的问题。我对zymud的回答有所帮助。因此,显然在documentation中,有一种方法可以序列化Generic关系。
因此,我要做的就是创建一个自定义字段并将该字段与序列化程序本身关联:
class ActivityObjectRelatedField(serializers.RelatedField):
def to_representation(self, value):
if isinstance(value, User):
return 'User: ' + value.username
elif isinstance(value, News):
return 'News: ' + value.title
elif isinstance(value, Job):
return 'Job: ' + value.title
elif isinstance(value, Tender):
return 'Tender: ' + value.title
raise Exception('Unexpected type of tagged object')
class ActivitySerializer(serializers.HyperlinkedModelSerializer):
actor = ActivityObjectRelatedField(read_only=True)
target = ActivityObjectRelatedField(read_only=True)
class Meta:
model = Activity
fields = ('url', 'actor', 'verb', 'target', 'pub_date')
关于django-rest-framework用于ContentType对象的序列化器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37930468/