В работе Django-rest-frame объект 'NoneType' не имеет атрибута 'attname' - PullRequest
0 голосов
/ 26 сентября 2018

Здесь я использую абстрактную концепцию, но когда я пытаюсь вызвать продукт, он выдает ошибку типа 'NoneType' object has no attribute 'attname'.

В этом models.py Product - основная модель, а другие модели, такие как Category, Reviews, Specification и ItemNumber, являются подмоделями.В Product все другие подмодели упоминаются как поля массива.

Я не знаю, как это преодолеть, поэтому, пожалуйста, скажите мне, как этого добиться.

Models.py

class Categories(models.Model):
   name = models.CharField(max_length=255)

   class Meta:
       abstract = True
class CategoriesForm(forms.ModelForm):
   class Meta:
       model = Categories
       fields = ['name']
class Specifications(models.Model):
   cost_price = models.FloatField()
   quantity = models.IntegerField()
   sell_price = models.FloatField()
   size = models.CharField(max_length=255)

   class Meta:
       abstract = True


class SpecificationsForm(forms.ModelForm):
   class Meta:
       model = Specifications
       fields = ['cost_price', 'quantity', 'sell_price', 'size']


class Reviews(models.Model):
   author = models.CharField(max_length=255)
   date = models.CharField(max_length=255)
   rating = models.FloatField()
   comment = models.CharField(max_length=1000)
   class Meta:
       abstract = True
class ReviewsForm(forms.ModelForm):
   class Meta:
       model = Reviews
       fields = ['author', 'date', 'rating', 'comment']

class ItemNumber(models.Model):
  spec_id = models.CharField(max_length=20)

  class Meta:
    abstract = True

class ItemNumberForm(forms.ModelForm):
  class Meta:
    model = ItemNumber
    fields = ['spec_id']
class Product(models.Model):
   name = models.CharField(max_length=255)
   image = models.ImageField(upload_to='', blank=True)
   categories = models.ArrayModelField(
       model_container=Categories,
       model_form_class=CategoriesForm
   )
   specifications = models.ArrayModelField(
       model_container=Specifications,
       model_form_class=SpecificationsForm
   )
   description = models.TextField()
   reviews = models.ArrayModelField(
       model_container=Reviews,
       model_form_class=ReviewsForm
   )
   drizzly = models.BooleanField()
   complete = models.BooleanField()
   comment = models.TextField()
   item_number = models.ArrayModelField(
       model_container=ItemNumber,
       model_form_class=ItemNumberForm
   )
   def __str__(self):
       return self.name

Serializer.py

class Productserializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'

1 Ответ

0 голосов
/ 26 сентября 2018

Краткий ответ : сделать модели не -абстрактными.

Я думаю, что вы на самом деле не понимаете концепцию абстрактных моделей,Абстрактная модель означает, что она на самом деле не существует: вы определяете столбцы, но для этой модели нет таблицы.Вы делаете это только так, что можете создать другую модель, которая наследует от абстрактных моделей, так что вы можете автоматически определять огромное количество столбцов, а также определенное общее поведение.Или, как указано в документации Django :

Абстрактные базовые классы полезны, когда вы хотите поместить некоторую общую информацию в ряд других моделей .Вы пишете свой базовый класс и помещаете abstract=True в класс Meta.Эта модель не будет использоваться для создания таблицы базы данных .Вместо этого, когда он используется в качестве базового класса для других моделей, его поля будут добавлены к полям дочернего класса.

Здесь, однако, вы определяете формы, сериализаторы и т. Д. Для этих абстрактных моделей.Это очень странно, поскольку как CategoriesForm удалось бы создать Categories объект, если вы - по замыслу - не сможете построить такие Categories объекты: вы можете только построить не -абстрактные объекты модели (которые могут или не могут наследоваться от одной или нескольких абстрактных моделей).

Ваши модели определены как абстрактные:

class Categories(models.Model):
   name = models.CharField(max_length=255)

   class Meta:
       <s><b>abstract = True</b></s>

ИтакВы должны пропустить это (и это, вероятно, применимо к большинству, если не ко всем моделям, которые вы определили).

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

python3 manage.py makemigrations

и затем перенастроить базу данных:

python3 manage.py migrate

Ошибка als появляется, если мы создаем абстрактную модель и создаем объект, например:

class Foo(models.Model):
    bar = models.IntegerField()

    class Meta:
        abstract = True

Тогда, если мы создадим такой объект, мы получим ту же ошибку:

>>> Foo(bar=12)
Traceback (most recent call last):
File "/usr/lib/python3.6/code.py", line 91, in runcode
exec(code, self.locals)
File "<console>", line 1, in <module>
File "/tmp/foo/.local/lib/python3.6/site-packages/django/db/models/base.py", line 513, in __repr__
return '<%s: %s>' % (self.__class__.__name__, self)
File "/tmp/foo/.local/lib/python3.6/site-packages/django/db/models/base.py", line 516, in __str__
return '%s object (%s)' % (self.__class__.__name__, self.pk)
File "/tmp/foo/.local/lib/python3.6/site-packages/django/db/models/base.py", line 564, in _get_pk_val
return getattr(self, meta.pk.attname)
AttributeError: 'NoneType' object has no attribute 'attname'

Примечание : номенклатура не совсем следует правилам.Обычно название модели - единственное число , поэтому Category вместо Categories и CategoryForm вместо CategoriesForm или CategoryForms.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...