Как использовать атрибут класса в его методе экземпляра в Django? - PullRequest
0 голосов
/ 06 января 2020

Я хочу использовать атрибут variation внутри функции to_representation в serializers.py. Когда я попытался реализовать это, произошла ошибка. Я думаю, что я все еще не понимаю основы Python класса.
Вот мой 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 дает мне эту ошибку при просмотре API:

AttributeError в / api / markets /
Объект 'MarketSerializer' не имеет атрибута 'variation'

В то время как 'variation': MarketSerializer.variation и 'variation': self.__class__.variation выдают мне эту ошибку:

AttributeError at / api / markets /
объект типа «MarketSerializer» не имеет атрибута «вариация»

Редактировать
'variation': variation дает мне эта ошибка:

NameError в / api / markets /
имя 'вариация' не определено

Ответы [ 2 ]

1 голос
/ 06 января 2020

Я не уверен, как это должно работать:

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

Поскольку в поле метода сериализатора метод должен выглядеть следующим образом:

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

Аналогично, вы можете использовать этот метод в to_represent метод:

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),
        }
 ...

Или лучше:

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
0 голосов
/ 06 января 2020

Поскольку вы пытаетесь получить доступ к экземпляру внешнего класса из внутреннего класса, используйте фабричный метод для создания экземпляра Inner и передачи ему экземпляра Outer. Мы не можем гарантировать существование внешнего класса при создании экземпляра внутреннего класса

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)
...