我想创建一个具有管理角色的应用程序,并且一个用户可以拥有多个角色。我在models.py中创建了两个模型,一个用于角色,另一个用于Users。我的models.py看起来像这样:
class Role(models.Model):
DOCTOR = 1
NURSE = 2
DIRECTOR = 3
ENGENEER = 4
ROLE_CHOICES = {
(DOCTOR, 'doctor'),
(NURSE, 'nurse'),
(DIRECTOR, 'director'),
(ENGENEER, 'engeneer'),
}
id = models.PositiveIntegerField(choices = ROLE_CHOICES, primary_key = True)
def __str__(self):
return self.get_id_display()
class User(AbstractUser):
roles = models.ManyToManyField(Role)
现在我要做的是从“用户”表单中建立角色。我的forms.py看起来像这样:
class UserCreationForm(UserCreationForm):
fields = ('username', 'password1', 'password2')
model = User
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].label = 'Insert username'
self.fields['password1'].label = 'Insert password'
self.fields['password2'].label = 'Again'
class RoleCreationForm(forms.ModelForm):
class Meta:
model = Role
fields = ('id',)
然后views.py看起来像这样:
class UserCreateView(CreateView):
model = User
form_class = forms.UserCreationForm
template_name = 'user_form.html'
redirect_field_name = 'index.html'
success_url = reverse_lazy('accounts:index')
class RoleCreateView(CreateView):
model = Role
form_class = forms.RoleCreationForm
template_name = 'role_form.html'
redirect_field_name = 'index.html'
success_url = reverse_lazy('accounts:index')
我该如何显示“用户”表单中的所有角色并从中选择多个角色?
答案 0 :(得分:1)
I assume your UserCreationForm
is subclass of forms.ModelForm
as well:
1) There are no password1
or password2
field in User
model - only password
. Hence, to make password confirmation you have to specify confirm_password
field and override clean
method to check that they are equal.
2) To show roles
in form, you can just specify 'roles'
in list of fields. Since roles
field exist in User
model, django will find correct widget, display and validate it correctly.
3) You didn't wrote about it, but I guess you added AUTH_USER_MODEL = '<you_app_name>.User'
to settings.py
? That will change default User
model to your app model.
4) Your UserCreateView
will store password in plain text, which is very bad idea. Read more about password management on how to properly store passwords.
class UserCreationForm(forms.ModelForm):
confirm_password = forms.CharField(widget=forms.PasswordInput())
class Meta:
fields = ('username', 'password', 'confirm_password', 'roles')
model = User
widgets = {
'password': forms.PasswordInput(),
'roles': forms.CheckboxSelectMultiple()
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].label = 'Insert username'
self.fields['password'].label = 'Insert password'
def clean(self):
cleaned_data = super().clean()
password = cleaned_data.get("password")
confirm_password = cleaned_data.get("confirm_password")
if password != confirm_password:
raise forms.ValidationError(
"password and confirm_password does not match"
)
In reality you probably want to just create additional model with OneToOneField
to User
and ManyToManyField
to Role
instead of overriding django User
, since replacing django User
model can lead to problems.
Check out django authentication views. You can subclass AuthenticationForm
to add Roles
.