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

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

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:

class MarketSerializer(serializers.ModelSerializer):
    regions = serializers.PrimaryKeyRelatedField(many=True, queryset=Region.objects.all())
    languages = serializers.PrimaryKeyRelatedField(many=True, queryset=Language.objects.all())
    variation = serializers.SerializerMethodField('get_product_variations')

    class Meta:
        model = Market
        fields = ['id', 'regions', 'languages', 'name', 'status', 'variation']
        depth = 1

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

    def to_representation(self, instance):
        if self.context['request'].method == 'GET':
            regions = RegionSerializer(instance.regions, many=True).data
            languages = LanguageSerializer(instance.languages, many=True).data

            data = {
                'id': instance.id,
                'regions': regions,
                'languages': languages,
                'name': instance.name,
                'status': instance.status,
                'variation': self.variation,
            }
            return data
        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:

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

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

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

Similarly, you can use that method in to_represent method:

def to_representation(self, instance):
  ...
  data = {
            'id': instance.id,
            'regions': regions,
            'languages': languages,
            'name': instance.name,
            'status': instance.status,
            'variation': self.get_product_variations(instance),
        }
 ...

Or better:

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

I am not sure how this suppose to work:

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

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

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

Similarly, you can use that method in to_represent method:

def to_representation(self, instance):
  ...
  data = {
            'id': instance.id,
            'regions': regions,
            'languages': languages,
            'name': instance.name,
            'status': instance.status,
            'variation': self.get_product_variations(instance),
        }
 ...

Or better:

def to_representation(self, instance):
      data = super().to_representation(instance)
      if self.context['request'].method == 'GET':
            data['regions'] = RegionSerializer(instance.regions, many=True).data
            data['languages'] = LanguageSerializer(instance.languages, many=True).data
      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"

class MarketSerializer(object):
    variation = 'h'

    def MarketSerializer(self):
        return MarketSerializer.Meta(self)

    class Meta(object):
        def __init__(self, market_serializer_instance):
            self.market_serializer_instance = market_serializer_instance

        def inner_method(self):
            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

class MarketSerializer(object):
    variation = 'h'

    def MarketSerializer(self):
        return MarketSerializer.Meta(self)

    class Meta(object):
        def __init__(self, market_serializer_instance):
            self.market_serializer_instance = market_serializer_instance

        def inner_method(self):
            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:

确定