#django #django-models #django-forms #uuid
#django #django-модели #django-forms #uuid
Вопрос:
ошибка получения — я сохранил одну форму из html в свою базу данных, а когда я попытался сохранить следующую, она выдала мне эту ошибку — Ошибка целостности у клиента (1062, «Дублирующая запись ‘ad138e46-edc0-11va-b065-a41g7252ecb4″ для ключа ‘customer.ПЕРВИЧНЫЙ'») пожалуйста, объясните мой uuid в models.py является —
class customer(models.Model):
customerid = models.CharField(default=str(uuid.uuid4()), max_length=500, primary_key=True)
customername=models.CharField(max_length=100)
пожалуйста, помогите
Обновлено
Form.py
class createcustomerform(ModelForm):
class Meta:
model=customer
fields=[
'customername']
Обновлено Models.py
import uuid
from uuid import UUID
from django.contrib.auth.models import User
from django.dispatch.dispatcher import receiver
from django.utils.translation import ugettext_lazy as _
from django.db.models.signals import pre_save
class customer(UUIDMixin,models.Model):
customername=models.CharField(max_length=100)
def __str__(self):
return self.customername
class UUIDMixin(models.Model):
uuid = models.UUIDField(blank=True,db_index=True,default=None,help_text=_('Unique identifier'),max_length=255,null=True,unique=True,verbose_name=_('UUID'))
class Meta:
abstract = True
@classmethod
def check_uuid_exists(cls, _uuid):
#Determine whether UUID exists """
manager = getattr(cls, '_default_manager')
return manager.filter(uuid=_uuid).exists()
@classmethod
def get_available_uuid(cls):
#Return an Available UUID """
row_uuid = uuid.uuid4()
while cls.check_uuid_exists(uuid=row_uuid):
row_uuid = uuid.uuid4()
return row_uuid
@receiver(pre_save)
def uuid_mixin_pre_save(sender, instance, **kwargs):
if issubclass(sender, UUIDMixin):
if not instance.uuid:
manager = getattr(instance.__class__, '_default_manager')
use_uuid = uuid.uuid4()
while manager.filter(uuid=use_uuid):
use_uuid = uuid.uuid4()
instance.uuid = use_uuid
#Automatically populate the uuid field of UUIDMixin models if not already populated.
Комментарии:
1. Почему бы не использовать
models.UUIDField
?2. Точно, используйте
models.UUIDField
, также добавьте свой код формы 🙂
Ответ №1:
Вы должны использовать правильный UUIDField
и избегать установки значения по умолчанию.
Убедитесь, что значение установлено при создании объекта, а также убедитесь, что значение уникально — очевидно, что вероятность дублирования в UUID невероятно мала, и в этом весь смысл.
Вы могли бы создать самостоятельно model mixin, который добавит uuid
к вашим моделям и гарантирует, что значение будет установлено при сохранении объекта;
class UUIDMixin(models.Model):
"""
Mixin for models contain a unique UUID, gets auto-populated on save
"""
uuid = models.UUIDField(
blank=True,
db_index=True,
# default=uuid.uuid4,
# NB: default is set to None in migration to avoid duplications
default=None,
help_text=_('Unique identifier'),
max_length=255,
null=True,
unique=True,
verbose_name=_('UUID'),
)
class Meta:
"""Metadata for the UUIDMixin class"""
abstract = True
@classmethod
def check_uuid_exists(cls, _uuid):
""" Determine whether UUID exists """
manager = getattr(cls, '_default_manager')
return manager.filter(uuid=_uuid).exists()
@classmethod
def get_available_uuid(cls):
""" Return an Available UUID """
row_uuid = uuid.uuid4()
while cls.check_uuid_exists(uuid=row_uuid):
row_uuid = uuid.uuid4()
return row_uuid
@receiver(pre_save)
def uuid_mixin_pre_save(sender, instance, **kwargs):
"""
Automatically populate the uuid field of UUIDMixin models if not already
populated.
"""
if issubclass(sender, UUIDMixin):
if not instance.uuid:
manager = getattr(instance.__class__, '_default_manager')
use_uuid = uuid.uuid4()
while manager.filter(uuid=use_uuid):
use_uuid = uuid.uuid4()
instance.uuid = use_uuid
Основываясь на вашем комментарии, позвольте мне объяснить больше.
Приведенная выше абстрактная модель, то есть она не создает саму таблицу, она может просто использоваться другими (конкретными) моделями, чтобы они могли использовать то, что она определяет.
Это преимущество классов и наследования. Позволяет вам не дублировать код для вещей, которые будут полезны во многих моделях.
Нет, в мете вы увидите abstract = True
. Итак, вы определяете свои модели следующим образом, MyModel(UUIDMixin, models.Model)
и он получает uuid
поле из этой абстрактной модели вместе с тем, что вы определяете.
Вы бы использовали его, сделав что-то вроде этого;
class Customer(UUIDMixin, models.Model):
name = models.CharField(max_length=100)
Если вы действительно хотите использовать UUID в качестве первичного ключа, возможно, установите два микшина, PrimaryUUIDMixin
и UUIDMixin
, потому что в целом меньшее значение в первичном ключе может быть более эффективным.
Вы также упомянули Undefined variable: _
Обычно в django вы увидите импорт в верхней части файла следующим образом;
from django.utils.translation import ugettext_lazy as _
Затем это используется для переноса строк, чтобы их можно было перевести, например, _("Hello")
Даже если вы не переводите свой проект, обычно просто включаете это в любом случае. Вы можете прочитать об этом здесь;https://docs.djangoproject.com/en/3.1/topics/i18n/translation/#standard-translation
Комментарии:
1. мой код, о котором идет речь, обновлен — как только я запускаю make migrations, выдает мне ошибку класса Customer(UUIDMixin, models. Модель): ошибка имени: имя ‘UUIDMixin’ не определено
2. @ritu ну, это означает, что python не может найти класс. Вам нужно поместить этот код куда-нибудь и импортировать его, чтобы его можно было использовать. Куда вы его помещаете, зависит от вас, и как вы организуете свой проект.
3. @ritu разместил ваш
UUIDMixin
класс над вашимcustomer
классом, и эта проблема с импортом должна быть решена. Просто небольшой совет, начните использовать правильные представления классов, подробнее читайте в документации Django, это сэкономит вам много времени позже.4. @ritu ваш класс объявляется первым. Поместите свою модель после другой, потому что
UUIDMixin
она должна существовать первой, чтобы другой класс мог ее использовать5. эй, я только что заметил, что на моей странице phpadmin в столбце UUID указано нулевое значение, почему это так, что он должен показывать какой-то UUID правильно?