Django get_or_create бросает ошибку целостности
Я прочитал эту тему: get_or_create бросает ошибку целостности
Но все еще не совсем понятно, когда get_or_create возвращает False или IntegrityError.
У меня есть следующий код:
django_username = 'me'
user = get_user_model().objects.filter(username=django_username).first()
action_history, action_added = ActionModel.objects.get_or_create(
date=date_obj, # date object
account_name=unique_name, # e.g. account1234
target=follower_obj, # another model in django
user=user, # connected django user
defaults={'identifier': history['user_id']}
)
В то время как модель выглядит следующим образом:
class ActionModel(models.Model):
"""
A model to store action history.
"""
identifier = models.BigIntegerField(
_("identifier"), null=True, blank=True) # target id
account_name = models.CharField(_("AccountName"), max_length=150, null=True, blank=True) # account name of the client
date = models.DateField(_("Date"), auto_now=False, auto_now_add=False) # action date
target = models.ForeignKey(Follower, verbose_name=_("Target"), on_delete=models.CASCADE) # username of the done-on action
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
null=True,
editable=False,
db_index=True,
) # django user that performed the action
class Meta:
verbose_name = _("Action")
verbose_name_plural = _("Actions")
unique_together = [
['account_name','date','target'],
]
Иногда он возвращает IntegrityError, а иногда (когда уникальное ограничение существует, оно вернет False при создании).
У вас есть ограничение unique_together. Представим, что у вас есть объект в базе данных со следующими данными имя_счета='bob', дата='2020-12-12', цель='b', пользователь='12'
В методе get_or_create вы делаете следующее
ActionModel.objects.get_or_create(
date='2020-12-12',
account_name='bob',
target='b',
user="13"
)
вы предоставляете именно эти три параметра с этими данными, но пользователь в этот раз 13, поэтому django не смог найти объект и пытается создать его, но с этими параметрами вы не можете создать объект, потому что есть уникальное ограничение
OK. Я разобрался, я послал:
account_name = 'adi'
date = '07-02-21'
target = 'nana1'
user = 'me'
Пока он не существовал с конкретным пользователем = 'me', но с пользователем = None:
account_name = 'adi'
date = '07-02-21'
target = 'nana1'
user = None
Итак, get был неудачным и созданная попытка дублировать unique_together = ['имя_счета','дата','цель'].