【问题标题】:ValueError: Field 'id' expected a number but got 'demo@gmail.com'ValueError:字段“id”需要一个数字,但得到了“demo@gmail.com”
【发布时间】:2021-12-05 06:24:20
【问题描述】:

我正在尝试创建一个用户模型,以便用户可以通过电子邮件地址而不是用户名进行注册。 当我尝试创建超级用户时,我得到了ValueError: Field 'id' expected a number but got 'demo@gmail.com'.,他们在makemigrations 和migrate 中没有问题

还尝试删除 pycache 以及所有旧迁移和 db 文件,但仍然相同。 colsole 输出也在最后 这里是模型

用户模型

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_("email address"), unique=True)
    first_name = models.CharField(_("first name"), max_length=10, blank=True)
    last_name = models.CharField(_("last name"), max_length=10, blank=True)
    date_joined = models.DateTimeField(_("date joined"), auto_now_add=True)
    is_active = models.BooleanField(_("is active"), default=True)

    # User Manager here
    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []
    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')
    
    def get_full_name(self):
        full_name = self.first_name + " " + self.last_name
        return full_name.strip()

用户管理器

class UserManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self,email,password, **extra_fields):
        """
        Create and save user
        """
        if not email:
            raise ValueError("Email is not available")
        email = self.normalize_email(email)
        user = self.model(email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user
    
    def create_user(self,email, password=None, **extra_fields):
        """
        Create a user
        """
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)
    
    def create_superuser(self,email, password, **extra_fields):
        """
        Create super user 
        """
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get("is_superuser") is not True:
            raise ValueError("Superuser must have is_superuser=True")

        return self._create_user(email, password, **extra_fields)

科尔松

(venv) D:\Python\Django\django-bookshop\bookshop>py manage.py createsuperuser
Email address: demo@gmail.com
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
Bypass password validation and create user anyway? [y/N]: y
Traceback (most recent call last):
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\db\models\fields\__init__.py", line 1823, in get_prep_value
    return int(value)
ValueError: invalid literal for int() with base 10: 'demo@gmail.com'

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

Traceback (most recent call last):
  File "D:\Python\Django\django-bookshop\bookshop\manage.py", line 22, in <module>
    main()
  File "D:\Python\Django\django-bookshop\bookshop\manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\core\management\__init__.py", line 419, in execute_from_command_line
    utility.execute()
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\core\management\__init__.py", line 413, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\core\management\base.py", line 354, in run_from_argv
    self.execute(*args, **cmd_options)
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\contrib\auth\management\commands\createsuperuser.py", line 79, in execute
    return super().execute(*args, **options)
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\core\management\base.py", line 398, in execute
    output = self.handle(*args, **options)
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\contrib\auth\management\commands\createsuperuser.py", line 189, in handle
    self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
  File "D:\Python\Django\django-bookshop\bookshop\account\managers.py", line 35, in create_superuser
    return self._create_user(email, password, **extra_fields)
  File "D:\Python\Django\django-bookshop\bookshop\account\managers.py", line 16, in _create_user
    user.save(using=self._db)
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\contrib\auth\base_user.py", line 67, in save
    super().save(*args, **kwargs)
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\db\models\base.py", line 726, in save
    self.save_base(using=using, force_insert=force_insert,
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\db\models\base.py", line 763, in save_base
    updated = self._save_table(
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\db\models\base.py", line 845, in _save_table
    updated = self._do_update(base_qs, using, pk_val, values, update_fields,
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\db\models\base.py", line 879, in _do_update
    filtered = base_qs.filter(pk=pk_val)
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\db\models\query.py", line 941, in filter
    return self._filter_or_exclude(False, args, kwargs)
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\db\models\query.py", line 961, in _filter_or_exclude
    clone._filter_or_exclude_inplace(negate, args, kwargs)
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\db\models\query.py", line 968, in _filter_or_exclude_inplace
    self._query.add_q(Q(*args, **kwargs))
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\db\models\sql\query.py", line 1393, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\db\models\sql\query.py", line 1412, in _add_q
    child_clause, needed_inner = self.build_filter(
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\db\models\sql\query.py", line 1347, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\db\models\sql\query.py", line 1193, in build_lookup
    lookup = lookup_class(lhs, rhs)
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\db\models\lookups.py", line 25, in __init__
    self.rhs = self.get_prep_lookup()
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\db\models\lookups.py", line 77, in get_prep_lookup
    return self.lhs.output_field.get_prep_value(self.rhs)
  File "D:\Python\Django\django-bookshop\venv\lib\site-packages\django\db\models\fields\__init__.py", line 1825, in get_prep_value
    raise e.__class__(
ValueError: Field 'id' expected a number but got 'demo@gmail.com'.

【问题讨论】:

    标签: python django django-models model


    【解决方案1】:

    在UserManager 的_create_user 函数中

    user = self.model(email, **extra_fields)
    

    应该是

    user = self.model(email=email, **extra_fields)
    

    当您像第一个代码中所示初始化模型时,参数会按照它们在模型中定义的顺序传递给字段。第一个字段将始终为id。默认情况下,Django 给每个模型一个自动递增的主键。(https://docs.djangoproject.com/en/3.2/topics/db/models/#automatic-primary-key-fields),所以这里的电子邮件值被分配给id。

    因此,您需要指定必须将值 email 分配给哪个字段。因此如第二个代码所示,您需要提供email=email

    【讨论】:

    • 成功了。谢谢,但为什么我只需要指定 email=email
    • @umairmehmood 为您的疑问添加了解释。如果答案清楚且有效,请接受答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-23
    • 2020-08-26
    • 1970-01-01
    • 2021-08-31
    • 1970-01-01
    相关资源
    最近更新 更多