Django 自定义用户 UUID 重复(缓存?)

Django Custom User UUID Duplicated (cached?)

我将 Django 与具有自定义 UUID 和自定义用户管理器的自定义用户模型一起使用:

class CustomUser(AbstractUser):
    id = models.UUIDField(primary_key=True, default=generate_id(), editable=False)
# ...

如您所见,我没有使用 default=uuid4()。相反,我自己创建了一个函数,它使用 uuid() 生成自定义 id 也使用时间戳:

from datetime import datetime as dt
from uuid import uuid1, uuid3, uuid4

def generate_id():
    timestamp = str(dt.timestamp(dt.now()))
    return uuid3(uuid4(),timestamp)

现在,如果我打开交互式 shell:python manage.py shell 并多次调用我的函数,这就是我得到的结果:

>>> generate_id()
UUID('bd8279f1-9b4b-3d7d-8932-f9e725f17045')
>>> generate_id()
UUID('0c2ec2ad-b062-3915-a9e9-22842c6f5ea2')
>>> generate_id()
UUID('2289202b-f252-3b27-bcae-cd44825bf4e0')
>>> generate_id()
UUID('88676ea9-4902-36ac-857d-929cb133089c')
>>> generate_id()
UUID('4a18b33e-12f0-3803-8ff0-0c4f0d1c849c')

但是当我尝试创建 2 个用户时:

from users.models import CustomUser
>>> one = CustomUser.objects.create_user(email='hhh@jaja.com',password='JJlsaks16112')
>>> two = CustomUser.objects.create_user(email='ttth@jija.com',password='JJlsaks16112')


Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/mysql/base.py", line 73, in execute
    return self.cursor.execute(query, args)
  File "/usr/local/lib/python3.8/site-packages/MySQLdb/cursors.py", line 206, in execute
    res = self._query(query)
  File "/usr/local/lib/python3.8/site-packages/MySQLdb/cursors.py", line 319, in _query
    db.query(q)
  File "/usr/local/lib/python3.8/site-packages/MySQLdb/connections.py", line 259, in query
    _mysql.connection.query(self, query)
MySQLdb._exceptions.IntegrityError: (1062, "Duplicate entry 'b448f583acfb31b7955926689b60f28a' for key 'PRIMARY'")

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/foodbook24-api/users/models.py", line 23, in create_user
    user.save()
  File "/usr/local/lib/python3.8/site-packages/django/contrib/auth/base_user.py", line 67, in save
    super().save(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 753, in save
    self.save_base(using=using, force_insert=force_insert,
  File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 790, in save_base
    updated = self._save_table(
  File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 895, in _save_table
    results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
  File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 933, in _do_insert
    return manager._insert(
  File "/usr/local/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/db/models/query.py", line 1254, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
  File "/usr/local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1397, in execute_sql
    cursor.execute(sql, params)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 98, in execute
    return super().execute(sql, params)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/mysql/base.py", line 73, in execute
    return self.cursor.execute(query, args)
  File "/usr/local/lib/python3.8/site-packages/MySQLdb/cursors.py", line 206, in execute
    res = self._query(query)
  File "/usr/local/lib/python3.8/site-packages/MySQLdb/cursors.py", line 319, in _query
    db.query(q)
  File "/usr/local/lib/python3.8/site-packages/MySQLdb/connections.py", line 259, in query
    _mysql.connection.query(self, query)
django.db.utils.IntegrityError: (1062, "Duplicate entry 'b448f583acfb31b7955926689b60f28a' for key 'PRIMARY'")

如果我进入数据库并修改我的第一个自定义用户的 ID,我可以创建第二个用户,但正如您从下面的屏幕截图中看到的那样,ID 没有改变!

我猜是缓存问题。任何人都知道我该如何解决它? (可能保留我的自定义 UUID 函数)谢谢。

您正在调用函数,因此default=… parameter [Django-doc]将设置为响应的结果,而不是函数,因此实际上,每次生成对象时,它都会使用该结果。

因此您应该传递对 callable 的引用,而不是结果:

class CustomUser(AbstractUser):
    #                                          <i>no</i> parenthesis ↓
    id = models.UUIDField(primary_key=True<b>, default=generate_id</b>, editable=False)