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)

Теперь он работает идеально.

Вернуться на верх