我正在创建一个员工注册页面以创建一个新用户(没有人登录过,即匿名用户)。我有一个Profile模型(添加了其他字段,例如Department,alias等),它是Django中User模型的扩展。我已将User视为与Profile的一对一关系。
新职员注册时,他们必须从ModelChoiceField引用Staff_Type表中指定其“ stafftypeid”(“职位”)。 User表不存储“ stafftypeid”,因此我扩展了UserCreationForm。
我的问题是我可以通过表单成功提交POST变量,并且用户(auth_user)将创建新记录。我可以在Django / admin页面中看到新用户。但是,个人档案将无法创建伴随的新记录,并且我收到一条错误消息(“ / register / (1048,“列'staffTypeID'不能为空”))。奇怪的是,我拥有所有POST变量,但没有传递Profile表中字段所需的变量。
这是继承问题吗?仅当您创建新用户时,才创建新的配置文件记录。
我尝试遵循Corey Schafer Django教程8,Simpleisbetterthancomplex(https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html#onetoone)和Stack Overflow中的教程和其他代码。
我还尝试过重新编写 def form.save(),然后将我的表单分成两个(最初只是一个),因为它在数据库方面更容易处理。我真的很感谢这里的建议!
Administrator \ models.py :(员工类型)
from django.db import models
from decimal import Decimal
class Staff_Type(models.Model):
stafftypeid = models.AutoField(db_column='staffTypeID', primary_key=True)
stafftypedesc = models.CharField(db_column='staffTypeDesc', max_length=150)
class Meta:
ordering = ['stafftypedesc']
unique_together = ('stafftypedesc',)
db_table = 'stafftype'
def __str__(self):
return self.stafftypedesc
Users \ models.py:
from django.db import models
from django.contrib.auth.models import User
from decimal import Decimal
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
stafftypeid = models.ForeignKey('Administrator.Staff_Type', models.DO_NOTHING, db_column='staffTypeID')
employeeid = models.CharField(max_length=20)
alias = models.CharField(max_length=20)
department = models.CharField(max_length=150)
organization = models.CharField(max_length=150)
fte = models.DecimalField(max_digits=4, decimal_places=1, default=Decimal(100.0))
def __str__(self):
return f'{self.user.username} Profile'
Users \ signals.py:
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.profile.save()
Users \ register.html:
{% extends "Administrator/adminBase.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="col-md-8">
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Register New User </legend>
{{ user_form|crispy }}
{{ profile_form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Sign Up</button>
</div>
</form>
</div>
</div>
{% endblock content %}
Users \ forms.py:
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from Administrator.models import Staff_Type
from .models import Profile
from .models import Profile
from django.utils.translation import ugettext_lazy as _
class UserRegisterForm(UserCreationForm):
email = forms.EmailField(max_length=150, label = "Email")
first_name = forms.CharField(max_length=150, label = "First Name")
last_name = forms.CharField(max_length=150, label = "Surname")
class Meta:
model = User
fields = ['username', 'email', 'first_name', 'last_name', 'password1', 'password2']
class ProfileForm(forms.ModelForm):
stafftypeid = forms.ModelChoiceField(queryset=Staff_Type.objects.all(), empty_label="Staff Type")
employeeid = forms.CharField(max_length=20, label="Employee ID")
alias = forms.CharField(max_length=20, label="Alias")
department = forms.CharField(max_length=150, label="Department")
organization = forms.CharField(max_length=150, label="Organization")
fte = forms.DecimalField(max_digits=4, decimal_places=1, min_value=0.0, max_value=100.0, label="FTE(%)")
class Meta:
model = Profile
fields = ['stafftypeid', 'employeeid', 'alias', 'department', 'organization', 'fte']
Users \ views.py:
from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import UserRegisterForm, ProfileForm
def register(request):
if request.method == "POST":
user_form = UserRegisterForm(request.POST)
profile_form = ProfileForm(request.POST)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
username = user_form.cleaned_data.get('username')
stafftypeid = profile_form.cleaned_data.get('stafftypeid')
messages.success(request, f'Account created for {username}, with alias: {stafftypeid}')
return redirect('admin-home')
else:
user_form = UserRegisterForm()
profile_form = ProfileForm()
return render(request, 'users/register.html', {'user_form': user_form, 'profile_form': profile_form})
Users \ apps.py:
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = 'users'
def ready(self):
import users.signals
答案 0 :(得分:0)
您的信号中出现错误。在那里,您只需创建一个配置文件,并仅设置用户字段,而无需设置其他任何字段。
您不需要此信号。您将在单独的“个人档案”表单中创建个人档案,并将其保存在视图中。您应该删除这两个信号。
然后,更新视图:
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
profile = profile_form.save(commit=False)
profile.user = user
profile.save()
(另外,请不要再将外键命名为以“ _id”结尾;它们不是ID,而是实际的相关对象。)