Django Rest Framework:为Serializer与ListSerializer添加方法的问题
解决DRF序列化器
many=True时自定义属性无法访问的问题 问题原因
当使用many=True序列化多个实例时,DRF会自动创建ListSerializer实例作为外层容器,而你定义的html_attrs属性仅存在于MySerializer类中,因此调用外层ListSerializer对象的该属性会触发AttributeError。
解决方案:自定义ListSerializer并传入上下文参数
通过自定义ListSerializer并为其添加对应的html_attrs属性,同时将bar值通过序列化器上下文传递,即可同时支持单个实例和多实例场景的属性调用。
步骤1:修改序列化器代码
from rest_framework import serializers # 自定义ListSerializer,添加html_attrs属性 class MyListSerializer(serializers.ListSerializer): @property def html_attrs(self): # 从上下文获取传入的bar值 bar = self.context.get('bar') return f'bar="{bar}"' class MySerializer(serializers.ModelSerializer): class Meta: model = Foo fields = '__all__' # 指定使用自定义的ListSerializer作为多实例序列化容器 list_serializer_class = MyListSerializer @property def html_attrs(self): # 单个实例场景:优先从实例取bar,没有则从上下文取 bar = self.instance.bar if hasattr(self.instance, 'bar') else self.context.get('bar') return f'bar="{bar}"'
步骤2:视图中传入上下文参数
bar = 123 # 从URL参数获取的bar值 instances = Foo.objects.filter(bar=bar).all() # 将bar传入序列化器上下文,确保ListSerializer能获取到该值 context['serializer'] = MySerializer(instances, many=True, context={'bar': bar})
替代方案(简化版)
如果不需要将属性逻辑封装在序列化器中,也可以直接在视图把bar变量传入模板上下文,在模板中直接拼接:
# 视图中 context['bar'] = bar
模板中直接使用:
bar="{{ bar }}"
内容的提问来源于stack exchange,提问作者run_the_race
相关产品推荐
相关产品推荐

