Ошибка атрибута в объекте / ‘Product’ не имеет атрибута ‘get_category_display’

#python #django #django-rest-framework

#python #django #django-rest-framework

Вопрос:

привет, я хочу, чтобы в моих продуктах api отображалось название категории вместо отображения идентификатора категории. Я написал функцию, чтобы сделать это для меня, но у меня есть эта ошибка:

  AttributeError at /
'Product' object has no attribute 'get_category_display'
 

как я могу это исправить?? есть мой сериализатор и модели категорий и продуктов

сериализаторы:

 class ProductSerializer(serializers.ModelSerializer):
    comments = serializers.SerializerMethodField()
    category = serializers.SerializerMethodField()

    class Meta:
        model = Product
        fields = ['id', 'category', 'name', 'slug', 'image_1',
                  'image_2', 'image_3', 'image_4', 'image_5',
                  'description', 'attribute', 'price', 'available', 'created', 'updated',
                  'popular', 'discount', 'comments']
        lookup_field = 'slug'
        extra_kwargs = {
            'url': {'lookup_field': 'slug'}
        }

    def get_comments(self, obj):
        comments_qs = Comment.objects.filter_parents_by_object(obj).order_by('posted')
        return CommentSerializer(comments_qs, many=True).data

    def get_category(self, obj):
        return obj.get_category_display()
 

Модели:

 class Category(models.Model):
    name = models.CharField(max_length=400)

    def __str__(self):
        return self.name


class Product(models.Model):
    category = models.ManyToManyField(Category, related_name='products')
    name = models.CharField(max_length=500)
    slug = models.SlugField(max_length=500, allow_unicode=True, unique=True)
    image_1 = models.ImageField(upload_to='products_pic/%Y/%m/%d/', null=True, blank=True)
   
    description = models.TextField(null=True, blank=True)
    attribute = models.JSONField(null=True, blank=True,
                                 help_text='in this format: {"key" : "value", "key2" : "value2"}')
    price = models.PositiveIntegerField()
    discount = models.PositiveIntegerField(null=True, blank=True)
    available = models.BooleanField(default=True)
    comments = GenericRelation(Comment)

    class Meta:
        ordering = ('-created',)

    def __str__(self):
        return self.name
 

Комментарии:

1. Пожалуйста, поделитесь своей Category и Product моделью.

2. я добавил свои модели.

Ответ №1:

Только поля со списком вариантов имеют a get_fieldname_display , вы можете представить имя объекта с помощью:

 def get_category(self, obj):
    return [str(c) for c in obj.category.all()] 

или, если Category модель имеет, например .name , поле, вы можете использовать:

 def get_category(self, obj):
    return [c.name for c in obj.category.all()] 

Комментарии:

1. я перешел на этот формат, но он возвращает Null

2. У меня есть категория, в которой отображается идентификатор, но когда я меняю код, он возвращает Null

3. @hossein-shahsavan: подождите, category это a ManyToManyField , поэтому существует не одна категория, а коллекция (из нуля, одной или нескольких категорий), поэтому вы не можете вернуть «имя категории». Вы можете, например, вернуть список названий категорий.

4. да, да. как я могу вернуть список категорий??

5. @hossein-shahsavan: да, но я бы посоветовал переименовать отношение categories или что-то множественное, поскольку теперь код «намекает», что он относится к одной категории.