django-rest-framework用于ContentType对象的序列化器

标签 django django-rest-framework django-contenttypes

我正在建立一个事件模型,有点类似于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/

相关文章:

django - 如何在 Django 中 order_by 通用关系?

python - 如何在 Django 选择中访问组名称?

python - 如何在 Django Rest Framework 序列化器中访问初始数据

python - 在 Django 中自动填充一组通用的多对多字段?

django-rest-framework - Django REST 框架 : how serializer context works?

python - 如何使用 REST Framework JWT 测试身份验证?

python - Django:ContentType.objects.get()抛出 "django.db.utils.ProgrammingError: relation "django_content_type“不存在”

python - Django MultiValueDictKeyError 什么时候发生以及如何避免?

python - 如何在 Django CharField 下启用默认值显示

Django - 设置过滤器字段标签或verbose_name