如果我们从html输入新的输入,UUID是否重复?

问题描述

遇到错误-我从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用作主键,则可以设置两个混合,分别是PrimaryUUIDMixinUUIDMixin,因为总体上,主键上的较小值可能更有效

您还提到了Undefined variable: _

通常在Django中,您会在文件顶部看到这样的导入内容;

from django.utils.translation import ugettext_lazy as _

然后用于包装字符串,以便可以翻译它们,例如_("Hello")

即使您不翻译项目,也无论如何都包含它是很常见的。您可以在这里阅读。 https://docs.djangoproject.com/en/3.1/topics/i18n/translation/#standard-translation