我在这里使用抽象概念,但是当我尝试调用产品时,它会抛出诸如'NoneType' object has no attribute 'attname'
之类的错误。
在此models.py中,产品是主要模型,而其他模型(例如,类别,评论,规格和ItemNumber)是子模型。在产品中,所有其他子模型都称为数组字段。
我不知道该如何克服这个问题,所以请告诉我如何实现这一目标。
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__'
答案 0 :(得分:2)
简短答案:使模型非抽象。
我认为您不太了解抽象模型的概念。抽象模型意味着它实际上并不存在:您定义列,但是该模型没有表。您这样做的唯一目的是可以创建另一个继承自抽象模型的模型,从而可以自动定义大量列以及某些常见行为。或如Django documentation中指定:
当您要添加一些常见内容时,抽象基类非常有用 信息导入其他许多模型。你写你的基类 并将
abstract=True
放在Meta
类中。然后,该模型将不被 用于创建任何数据库表。而是当它用作基础时 其他模型的类,其字段将添加到孩子的字段中 课。
但是,您在这里定义了这些抽象模型的形式,序列化器等。这很奇怪,因为如果设计使您无法构造CategoriesForm
,Categories
将如何设法创建Categories
对象对象:您只能构造 non 非抽象模型对象(可能会也可能不会从一个或多个抽象模型继承)。
您的模型定义为摘要:
class Categories(models.Model):
name = models.CharField(max_length=255)
class Meta:
abstract = True
因此您应该忽略这一点(这可能适用于您定义的大多数(如果不是全部)模型)。
然后,您还必须在数据库中构造表。您可以通过进行迁移来做到这一点:
python3 manage.py makemigrations
然后迁移数据库:
python3 manage.py migrate
如果我们创建一个抽象模型并创建一个对象,则会显示错误消息,例如:
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
代替{{ 1}}或。CategoriesForm