在Django中,扩展User模型后,如何向新模型添加值?

nxowjjhe  于 2023-07-01  发布在  Go
关注(0)|答案(2)|浏览(139)

我在Django中扩展了User模型,并在4.2版本中添加了一个名为“Account”的配置文件模型。Django管理面板成功地将“Account”模型作为一个部分列出,它在Django管理面板中工作得很好。
我想在用户注册时在帐户模型中设置一个值“移动的_number”。现在我可以在Django管理面板中手动完成,但我需要在用户注册时更新。
models.py 代码:

from django.db import models
from django.contrib.auth.models import User

class Account(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    mobile_number = models.CharField(max_length=10)
    def __str__(self):
        return f"{self.user.username} ({self.user.first_name})"

admin.py 代码:

from django.contrib import admin
from accounts.models import Account
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin

# Register your models here.
class AccountInline(admin.StackedInline):
    model = Account
    can_delete = False
    verbose_name_plural = 'Accounts'

class CustomisedUserAdmin (UserAdmin):
    inlines = (AccountInline, )

admin.site.unregister(User)
admin.site.register(User, CustomisedUserAdmin) 
admin.site.register(Account)

views.py 代码:

def register(request):
    if request.method == "POST":
        username = request.POST['username']
        first_name = request.POST['first_name']
        last_name = request.POST['last_name']
        email = request.POST['email']
        password1 = request.POST['password1']
        password2 = request.POST['password2']
        mobile_number = request.POST['mobile_number']
        if password1 == password2:
            if User.objects.filter(email=email).exists():
                messages.info(request, "Email already registered")
                return redirect('register')
            elif User.objects.filter(username=username).exists():
                messages.info(request, "Username already registered")
                return redirect('register')
            else:
                user = User.objects.create_user(username=username, first_name=first_name, last_name=last_name, email=email, password=password1)
                mobile_number = user.Account.mobile_number
                user.save();
                return redirect('login')
        else:
            messages.info(request, "Password not the same")
            return redirect('register')
    else:    
        return render(request, 'register.html')

我得到错误:

AttributeError at /accounts/create
'User' object has no attribute 'Account'
yr9zkbsy

yr9zkbsy1#

只要我理解正确,你现在经历的是:
您正在尝试为用户创建新帐户,但Django管理员首先为您提供了创建用户名和密码的屏幕。
而你要做的是:
在为新用户创建新帐户时,您还希望同时修改mobile_number,而不是在实际创建帐户后手动编辑mobile_number
如果我上面的理解是正确的,那么我猜这是因为你正在扩展UserAdmin,它包含了创建用户的基本逻辑,包括哈希密码。
为了避免这种情况,您可以只扩展admin.ModelAdmin类,但随后您需要包含单独的逻辑来自己散列密码,因为保存密码而不将其散列到数据库中是至关重要的。

jbose2ul

jbose2ul2#

正如错误所说,用户没有帐户。在您的register视图中,您从未为User创建过Account(例如:Account.objects.create(user=user, mobile_number=mobile_number)。
也就是说,有一些方法可以改进和清理代码。通过使用django forms,在本例中更具体地基于内置表单:
forms.py

class UserForm(UserCreationForm):
    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = ("username", "first_name", "last_name", 
                  "email", "password1", "password2")

这个表单将负责所有的验证(你在视图中所做的),并且还提供了其他优点:
views.py

def register(request):
    if request.method == "POST":
        form = UserForm(request.POST)
        if form.is_valid():
            user = form.save()
            mobile_number = request.POST.get("mobile_number")
            Account.objects.create(user=user, mobile_number=mobile_number)
            redirect("register")
    else:
        form = UserForm()

    return render(request, "register.html", {"form": form})

register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form method="post" action="{% url 'register' %}">
        {% csrf_token %}
        {{form.as_p}}
        <div style="margin: 10px 10px 10px 0;">
            <label for="mobile_number">Mobile Number: </label>
            <input id="mobile_number" name="mobile_number" type="text"/>
        </div>
        <button type="submit">Save</button>
    </form>
</body>
</html>

相关问题