Cur*_*984 24 django django-models django-rest-framework
我有两个模型,一个具有M2M关系和相关名称.我想在序列化程序和相关字段中包含所有字段.
models.py:
class Pizza(models.Model):
name = models.CharField(max_length=50, unique=True)
toppings = models.ManyToManyField(Topping, null=True, blank=True, related_name='pizzas')
class Topping(models.Model):
name = models.CharField(max_length=50, unique=True)
price = models.IntegerField(default=0)
Run Code Online (Sandbox Code Playgroud)
serializer.py:
class ToppingSerializer(serializers.ModelSerializer):
class Meta:
model = Topping
fields = '__all__'
Run Code Online (Sandbox Code Playgroud)
这有效,但不包括相关字段.
fields = ['name', 'price', 'pizzas']
Run Code Online (Sandbox Code Playgroud)
这完全符合我的要求,但当Toppings模型有很多字段时会发生什么.我想做的事情如下:
fields = ['__all__', 'pizzas']
Run Code Online (Sandbox Code Playgroud)
此语法导致错误说:
字段名称
__all__
对于模型无效
有没有办法实现想要的行为?或者在使用相关名称时必须手动输入字段?
hug*_*tti 29
就像@DanEEStart所说的那样,DjangoRestFramework没有一种简单的方法来扩展字段的' all '值,因为这些get_field_names
方法似乎是按照这种方式设计的.
但幸运的是,您可以覆盖此方法,以允许一种简单的方法来包含所有字段和关系,而无需枚举大量字段.
我像这样重写这个方法:
class ToppingSerializer(serializers.ModelSerializer):
class Meta:
model = Topping
fields = '__all__'
extra_fields = ['pizzas']
def get_field_names(self, declared_fields, info):
expanded_fields = super(ToppingSerializer, self).get_field_names(declared_fields, info)
if getattr(self.Meta, 'extra_fields', None):
return expanded_fields + self.Meta.extra_fields
else:
return expanded_fields
Run Code Online (Sandbox Code Playgroud)
请注意,此方法仅更改此序列化程序的行为,并且该extra_fields
属性仅适用于此序列化程序类.
如果你有这么多的序列化器,你可以创建一个中间类,将这个get_fields_names
方法包含在一个地方并重复使用多次.有人喜欢这样:
class CustomSerializer(serializers.HyperlinkedModelSerializer):
def get_field_names(self, declared_fields, info):
expanded_fields = super(CustomSerializer, self).get_field_names(declared_fields, info)
if getattr(self.Meta, 'extra_fields', None):
return expanded_fields + self.Meta.extra_fields
else:
return expanded_fields
class ToppingSerializer(CustomSerializer):
class Meta:
model = Topping
fields = '__all__'
extra_fields = ['pizzas']
class AnotherSerializer(CustomSerializer):
class Meta:
model = Post
fields = '__all__'
extra_fields = ['comments']
Run Code Online (Sandbox Code Playgroud)
Dan*_*tar 18
我刚检查了Django Rest Framework的源代码.框架中似乎不支持您想要的行为.
该fields
选项必须是列表,元组或文本__all__
.
以下是相关源代码的片段:
ALL_FIELDS = '__all__'
if fields and fields != ALL_FIELDS and not isinstance(fields, (list, tuple)):
raise TypeError(
'The `fields` option must be a list or tuple or "__all__". '
'Got %s.' % type(fields).__name__
)
Run Code Online (Sandbox Code Playgroud)
您不能在元组或列表中添加" all "以及字段...
Aik*_*y30 12
一个老问题,但认为这可能在将来帮助其他人.
我刚刚遇到类似的问题并通过手动指定其他字段来完成" 全部 "选项,如下例所示.我不确定这是否也可以解决您的问题.这是一个比我见过的任何其他东西更干净的视线.
http://www.django-rest-framework.org/api-guide/relations/#nested-relationships
class TrackSerializer(serializers.ModelSerializer):
class Meta:
model = Track
fields = '__all__'
class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackSerializer(many=True, read_only=True)
class Meta:
model = Album
fields = '__all__'
Run Code Online (Sandbox Code Playgroud)
我认为这适用于同一页面上列出的任何其他相关字段选项:http://www.django-rest-framework.org/api-guide/relations/#serializer-relations
我正在使用Django Rest Framework版本3.6.2
请求的反向关系示例:
class TrackSerializer(serializers.ModelSerializer):
album = AlbumSerializer(source='album_id')
class Meta:
model = Track
fields = '__all__'
Run Code Online (Sandbox Code Playgroud)
Ele*_*wen 10
如果您基本上只是尝试将额外的信息添加到序列化对象中,则根本不需要更改字段部分。要添加字段,请执行以下操作:
class MySerializer(serializers.ModelSerializer):
...
new_field = serializers.SerializerMethodField('new_field_method')
def new_field_method(self, modelPointer_):
return "MY VALUE"
Run Code Online (Sandbox Code Playgroud)
然后你仍然可以使用
class Meta:
fields = '__all__'
Run Code Online (Sandbox Code Playgroud)
小智 8
嗨,我可以使用Django的_meta API达到预期的结果,该API自Django 1.11起似乎可用。所以在我的序列化器中,我做了:
model = MyModel
fields = [field.name for field in model._meta.fields]
fields.append('any_other_field')
Run Code Online (Sandbox Code Playgroud)
在编程中,总是有很多方法可以达到相同的结果,但是上面的方法对我来说确实有效。
干杯!
归档时间: |
|
查看次数: |
17892 次 |
最近记录: |