【问题标题】:Duplicate UUID if we enter a new input from html?如果我们从 html 输入新的输入,UUID 会重复吗?
【发布时间】:2020-09-03 10:47:24
【问题描述】:

出现错误-我将一个表单从 html 保存到我的数据库中 当我尝试保存下一个时,它给了我这个错误- 客户的IntegrityError (1062,“重复条目 'ad138e46-edc0-11va-b065-a41g7252ecb4'' 键'customer.PRIMARY'”) 请解释我在 models.py 中的 uuid 是 -

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.

【问题讨论】:

  • 为什么不使用models.UUIDField
  • 没错,使用models.UUIDField,同时添加您的表单代码:)

标签: django django-models django-forms uuid


【解决方案1】:

您应该使用正确的UUIDField 并避免设置默认值。

确保在创建对象时设置该值,并确保该值是唯一的 - 显然,在 UUID 中重复的机会非常小,这是重点。

您可以自己创建一个模型 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 作为主键,可以设置两个 mixin,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

【讨论】:

  • 我有问题的代码更新了——只要我运行 make migrations 就会给我错误类 Customer(UUIDMixin, models.Model): name error: name 'UUIDMixin' is not defined
  • @ritu 很好,这意味着 python 找不到该类。您需要将该代码放在某处并导入它以便可以使用。你把它放在哪里,以及你如何组织你的项目。
  • @ritu 将您的 UUIDMixin 类放在您的 customer 类之上,应该解决导入问题。只是一点建议,开始使用正确的类视图,阅读更多关于 Django 文档的内容,以后会为你节省很多时间。
  • @ritu 你的班级首先被声明。将您的模型放在另一个模型之后,因为 UUIDMixin 需要首先存在才能让其他类使用它
  • 嘿,我刚刚注意到,在我的 phpadmin 页面中,UUID 列下给出了 Null 值,为什么它应该显示一些 UUID 对吗?
猜你喜欢
  • 1970-01-01
  • 2021-03-27
  • 1970-01-01
  • 2023-03-23
  • 2019-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-26
相关资源
最近更新 更多