您的位置:

最佳方案处理django Exception("Oops, that's his last name")

  发布时间:2025-03-13 22:03:02
该文章讨论了在Django中出现异常的原因和解决方案。问题可能是由于未知查询参数导致结果为null,或是使用不允许的字段名如"last_name"。解决方法包括自定义模型表单和使用Django内置User模型。文章给出了代码示例和具体操作步骤。另外,介绍了出现异常的具体例子,如在django-allauth库中的异常并提供了解决方案。

问题原因

该异常出现的原因是由于在Django中,使用get()或者filter()等查询方法时,传递了未知的查询参数,导致查询结果为null,而在后续的操作中尝试访问该结果的属性时触发了异常。

解决方案

该异常出现是因为Django默认情况下不允许用户在表单中使用"last_name"作为字段名。为了解决这个问题,可以通过自定义模型表单来更改字段名,或者使用Django内置的User模型来避免这个问题。

解决方法:

  1. 自定义模型表单:创建一个新的模型表单,通过重命名字段来避免使用"last_name"这个字段名。例如,可以将"last_name"改为"family_name"。

from django import forms
from yourapp.models import YourModel

class YourModelForm(forms.ModelForm):
    family_name = forms.CharField(max_length=100)  # 使用新的字段名

    class Meta:
        model = YourModel
        fields = ['family_name', 'other_fields']
  1. 使用Django内置的User模型:如果问题出现在用户模型中,推荐使用Django内置的User模型,避免重复定义用户相关信息。可以直接使用User模型提供的"last_name"字段而不需要自定义用户模型。

from django.contrib.auth.models import User

user = User.objects.create_user(username='username', email='email@example.com', password='password')
user.last_name = 'Smith'
user.save()

示例:

假设我们有一个用户信息的模型如下:


from django.db import models

class UserProfile(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    email = models.EmailField()

    def __str__(self):
        return self.first_name + ' ' + self.last_name

我们可以通过自定义模型表单来解决"last_name"字段名导致的异常


from django import forms
from .models import UserProfile

class UserProfileForm(forms.ModelForm):
    family_name = forms.CharField(max_length=100)  # 使用新的字段名

    class Meta:
        model = UserProfile
        fields = ['first_name', 'family_name', 'email']

通过以上两种方法,可以解决Django出现Exception("Oops, that's his last name")的问题。

具体例子

在Django中出现Exception("Oops, that's his last name")通常是由于在项目中使用了django-allauth库时,尝试使用用户的姓氏作为用户名而导致的。这个异常的原因是django-allauth不允许将用户的姓氏作为用户名。为了解决这个问题,可以通过自定义用户名生成器来避免将用户的姓氏作为用户名。 下面是一个正确使用django-allauth并解决Exception("Oops, that's his last name")异常的例子:


# settings.py
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_UNIQUE_EMAIL = True

# Custom Username Generation
from allauth.account.utils import valid_username

def custom_username_generator(user):
    username = user.email.split('@')[0]
    if not valid_username(username):
        username = user.email
    return username

ACCOUNT_USERNAME_BLACKLIST = ['admin', 'superuser', 'username', 'email']
ACCOUNT_USERNAME_VALIDATORS = 'myapp.validators.custom_username_validator'
ACCOUNT_USERNAME_MIN_LENGTH = 3

ACCOUNT_USERNAME_GENERATOR = 'myapp.utils.custom_username_generator'

# validators.py
from django.core.exceptions import ValidationError

def custom_username_validator(value):
    if value.isdigit():
        raise ValidationError("Username cannot be fully numeric.")

# utils.py
def custom_username_generator(user):
    username = user.email.split('@')[0]
    if not valid_username(username):
        username = user.email
    return username

通过以上配置,我们自定义了用户名生成器custom_username_generator,并在其中避免了使用用户的姓氏作为用户名。同时,我们还设置了一些用户名的验证规则和黑名单,确保生成的用户名符合要求。这样,在使用django-allauth时,就可以避免出现Exception("Oops, that's his last name")异常。 以上是关于如何正确使用django-allauth并解决Exception("Oops, that's his last name")异常的说明和示例。