如何在Django的实例方法中使用类属性?

huangapple go评论117阅读模式
英文:

How to use class attribute in its instance method in Django?

问题

'variation': self.variation 给我这个错误信息在可浏览的API中:

在 /api/markets/ 处的 AttributeError
'MarketSerializer' 对象没有 'variation' 属性

'variation': MarketSerializer.variation'variation': self.__class__.variation 给我这个错误信息:

在 /api/markets/ 处的 AttributeError
类型对象 'MarketSerializer' 没有 'variation' 属性

编辑
'variation': variation 给我这个错误信息:

在 /api/markets/ 处的 NameError
名称 'variation' 未定义

英文:

I want to use variation attribute inside to_representation function in serializers.py. When I tried to implement it an error occured. I think I still don't understand the fundamental of Python class.
Here's my serializers.py:

  1. class MarketSerializer(serializers.ModelSerializer):
  2. regions = serializers.PrimaryKeyRelatedField(many=True, queryset=Region.objects.all())
  3. languages = serializers.PrimaryKeyRelatedField(many=True, queryset=Language.objects.all())
  4. variation = serializers.SerializerMethodField('get_product_variations')
  5. class Meta:
  6. model = Market
  7. fields = ['id', 'regions', 'languages', 'name', 'status', 'variation']
  8. depth = 1
  9. @staticmethod
  10. def get_product_variations(self):
  11. return Product.objects.filter(distributor__region__market=self).distinct().count()
  12. def to_representation(self, instance):
  13. if self.context['request'].method == 'GET':
  14. regions = RegionSerializer(instance.regions, many=True).data
  15. languages = LanguageSerializer(instance.languages, many=True).data
  16. data = {
  17. 'id': instance.id,
  18. 'regions': regions,
  19. 'languages': languages,
  20. 'name': instance.name,
  21. 'status': instance.status,
  22. 'variation': self.variation,
  23. }
  24. return data
  25. return Serializer.to_representation(self, instance)

'variation': self.variation gives me this error on browsable API:

> AttributeError at /api/markets/
> 'MarketSerializer' object has no attribute 'variation'

While 'variation': MarketSerializer.variation and 'variation': self.__class__.variation give me this error:
> AttributeError at /api/markets/
> type object 'MarketSerializer' has no attribute 'variation'

Edit
'variation': variation gives me this error:

> NameError at /api/markets/
> name 'variation' is not defined

答案1

得分: 1

I am not sure how this suppose to work:

  1. @staticmethod
  2. def get_product_variations(self):
  3. return Product.objects.filter(distributor__region__market=self).distinct().count()

Because, in serializer method field, the method should be like this:

  1. def get_product_variations(self, obj):
  2. # not a static method
  3. return Product.objects.filter(distributor__region__market=obj).distinct().count()

Similarly, you can use that method in to_represent method:

  1. def to_representation(self, instance):
  2. ...
  3. data = {
  4. 'id': instance.id,
  5. 'regions': regions,
  6. 'languages': languages,
  7. 'name': instance.name,
  8. 'status': instance.status,
  9. 'variation': self.get_product_variations(instance),
  10. }
  11. ...

Or better:

  1. def to_representation(self, instance):
  2. data = super().to_representation(instance)
  3. if self.context['request'].method == 'GET':
  4. data['regions'] = RegionSerializer(instance.regions, many=True).data
  5. data['languages'] = LanguageSerializer(instance.languages, many=True).data
  6. return data
英文:

I am not sure how this suppose to work:

  1. @staticmethod
  2. def get_product_variations(self):
  3. return Product.objects.filter(distributor__region__market=self).distinct().count()

Because, in serializer method field, the method should be like this:

  1. def get_product_variations(self, obj):
  2. # not a static method
  3. return Product.objects.filter(distributor__region__market=obj).distinct().count()

Similarly, you can use that method in to_represent method:

  1. def to_representation(self, instance):
  2. ...
  3. data = {
  4. 'id': instance.id,
  5. 'regions': regions,
  6. 'languages': languages,
  7. 'name': instance.name,
  8. 'status': instance.status,
  9. 'variation': self.get_product_variations(instance),
  10. }
  11. ...

Or better:

  1. def to_representation(self, instance):
  2. data = super().to_representation(instance)
  3. if self.context['request'].method == 'GET':
  4. data['regions'] = RegionSerializer(instance.regions, many=True).data
  5. data['languages'] = LanguageSerializer(instance.languages, many=True).data
  6. return data

答案2

得分: 0

"Since you are trying to access the outer class instance from an inner class, use factory-method to build Inner instance and pass Outer instance to it. We can not guarantee the existence of an outer class when you create an instance of the inner class"

  1. class MarketSerializer(object):
  2. variation = 'h'
  3. def MarketSerializer(self):
  4. return MarketSerializer.Meta(self)
  5. class Meta(object):
  6. def __init__(self, market_serializer_instance):
  7. self.market_serializer_instance = market_serializer_instance
  8. def inner_method(self):
  9. print(self.market_serializer_instance.variation)
英文:

Since you are trying to access the outer class instance from an inner class, use factory-method to build Inner instance and pass Outer instance to it.
We can not guarantee the existence of an outer class when you create an instance of the inner class

  1. class MarketSerializer(object):
  2. variation = 'h'
  3. def MarketSerializer(self):
  4. return MarketSerializer.Meta(self)
  5. class Meta(object):
  6. def __init__(self, market_serializer_instance):
  7. self.market_serializer_instance = market_serializer_instance
  8. def inner_method(self):
  9. print(self.market_serializer_instance.variation)

huangapple
  • 本文由 发表于 2020年1月6日 15:50:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/59608435.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定