Django DETAIL: Неудачная строка содержит (11, SG 553, BATTLE-SCARRED, CLASSIFIED, NORMAL, RIFLE, null, 6235.05)
Задача по созданию Оружия объектов:
def populate_weapon_objects(amount: int = 1) -> None:
for _ in range(amount):
Weapon.objects.create(
name=_get_random_name(),
exterior=_get_random_exterior(),
quality=_get_random_quality(),
category=_get_random_category(),
price=_get_random_price(),
)
Оружие модель:
class Weapon(models.Model):
...
name = models.CharField(max_length=64, choices=WEAPONS, db_index=True)
exterior = models.CharField(max_length=64, choices=EXTERIOR, default=EXTERIOR_FACTORY_NEW, db_index=True)
quality = models.CharField(max_length=64, choices=QUALITY, default=QUALITY_CONSUMER_GRADE, db_index=True)
category = models.CharField(max_length=64, choices=CATEGORY, default=CATEGORY_NORMAL, db_index=True)
type = models.CharField(max_length=64, editable=False, db_index=True)
slug = models.SlugField(max_length=64, editable=False, unique=True, db_index=True)
price = models.FloatField(validators=[MinValueValidator(0), MaxValueValidator(10**4)], db_index=True)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
if not self.type:
self.type = self._get_type_by_name()
if not self.slug:
self.slug = self._get_slug()
return super().save(*args, **kwargs)
def _get_type_by_name(self) -> str:
return next(k for k, v in self.NAME_TO_TYPE_DICT.items() if self.name in v)
def _get_slug(self) -> None:
self.slug = generate_slug(self)
generate_slug функция:
def generate_slug(weapon) -> str:
name = weapon.name
exterior = weapon.exterior
quality = weapon.quality
category = weapon.category
sequence = [name, exterior, quality, category]
slug = slugify(' '.join(sequence))
return slug
Это приводит к:
django.db.utils.IntegrityError: null value in column "slug" of
relation "weapons_weapon" violates not-null constraint
celery-worker | DETAIL: Failing row contains (14, PP-BIZON,
MINIMAL WEAR, RESTRICTED, NORMAL, SMG, null, 7354.3,
2022-09-15 13:15:43.75499+00, 2022-09-15 13:15:43.754978+00).
Почему это происходит? Почему при создании объекта type заполняется поле Weapon, а поле slug продолжает разрушаться (не заполняется)? Пожалуйста, помогите.
Разве метод create()
не вызывает метод save()
объекта? Я четко уверен, что да. Но почему тогда self.type получает значение, а self.slug нет?
Я нашел решение. Оно было в методе _get_slug
def _get_slug(self) -> None:
self.slug = generate_slug(self)
Он возвращал NoneType + он уже пытался присвоить значение полю slug. Почему я говорю "пытался", потому что затем в методе save
он снова присваивал значение return метода _get_slug, которое является None:
if not self.slug:
self.slug = self._get_slug() # returns None
Я изменил свой код на:
def _get_slug(self) -> str:
return generate_slug(self)
Теперь он работает идеально.