如何使用'__all__'将@property字段添加到django rest serializer

时间:2018-03-05 09:41:47

标签: django-rest-framework

我有模特

class A(models.Model):
    is_enable = models.BooleanField(default=False)
    title = models.CharField(max_length=255, blank=True, null=True)
    updated_date = models.DateTimeField(auto_now=True)
    show_count = models.IntegerField(default=0)
    answers_count = models.IntegerField(default=0)
    audience = JSONField()
    events = JSONField()
    rules = JSONField()
    message = models.TextField(blank=True)

    @property
    def conversion(self):
        if self.show_count == 0:
            return 0.0
        return (self.answers_count / self.show_count) * 100

我有序列化器

class ASerializer(serializers.ModelSerializer):
    audience = serializers.JSONField()
    events = serializers.JSONField()
    rules = serializers.JSONField()

    class Meta:
        model = Trigger
        fields = '__all__'

我想添加到响应@property conversion`字段 我想在序列化器中做这样的事情

class Meta:
            model = Trigger
            fields = '__all__' + conversion

我知道我可以做这样的事情

class Meta:
                model = Trigger
                fields = ('is_enable', 'title' ... 'conversion')

但我想添加所有字段和转换字段,并使其更美观

3 个答案:

答案 0 :(得分:0)

你可以使用像这样的东西:

class ModelMixin:
    @classmethod
    def _get_model_fields(cls):
        all_fields = cls._meta.get_fields()
        fields = [i.name for i in all_fields if i.__class__.__name__ not in ['ManyToManyRel', 'GenericRelation', 'ManyToOneRel']]
        return fields
    @classmethod
    def get_serializer_fields(cls):
        fields = cls._get_model_fields()
        return fields

class A(ModelMixin, models.Model):
    ...

class ASerializer(ModelSerializer):
    custom_field = serializers.JSONField()
    class Meta:
        model = A
        fields = A.get_serializer_fields()
        fields.append('cusom_field')

答案 1 :(得分:0)

可能仍然不够理想,但是使用<model>._meta.fields可以获取该模型的所有字段,使用每个字段的name属性可以检索到参考他们。 由于序列化程序文件被解释为python,因此它支持代码执行,这意味着您可以在设置属性(包括for循环)时使用所有python功能,从而使我们能够执行以下操作:

fields = (tuple((f.name for f in A._meta.fields)) + ('conversion',))

我自己的模型也需要它,并且似乎可以正常工作,所以希望对您也是如此。

答案 2 :(得分:0)

您可以在序列化器中创建一个 SerializerMethodField ,然后在序列化器本身中定义一个方法,该方法可以使用@property 调用您在模型中定义的函数

class ASerializer(serializers.ModelSerializer):
    audience = serializers.JSONField()
    events = serializers.JSONField()
    rules = serializers.JSONField()
    conversion = serializers.SerializerMethodField()

    class Meta:
        model = Trigger
        fields = '__all__'
    
    def get_conversion(self,obj):
        return obj.conversion

这应该允许您保持代码美观而无需修改大量代码。