问题描述
遇到错误-我从html中保存了一种表单到我的数据库中 当我尝试保存下一个时,它给了我这个错误- 客户的完整性错误 (1062,“键“ customer.PRIMARY”的条目重复'ad138e46-edc0-11va-b065-a41g7252ecb4”) 请在models.py中解释我的uuid-
@H_502_5@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
@H_502_5@class createcustomerform(ModelForm): class Meta: model=customer fields=[ 'customername']
更新了 Models.py
@H_502_5@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.
解决方法
您应使用适当的UUIDField
,并避免设置默认值。
请确保在创建对象时设置了该值,并确保该值是唯一的-显然,UUID中重复的机会非常小,这很重要。
您可以创建自己的模型混合,将为模型添加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