用户表单未显示基于 django class 的视图
User Form not showing django class based views
我在医院管理系统上工作,有 5-6 种不同类型的用户,如患者、医生、护士、会计师、接待员等。我使用 AbstractUser
扩展了用户模型,它具有所有用户的公共字段,如 DoB、地址等。
models.py
class User(AbstractUser):
# user_type = models.CharField(choices=USER_TYPES, default='patient', max_length=20)
date_of_birth = models.DateField(blank=True, null=True, validators=[validate_future_date])
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+9199999999'. Up to 15 digits allowed.")
mobile_num = models.CharField(max_length=15, validators=[phone_regex])
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
date_joining = models.DateTimeField(auto_now_add=True)
photo = models.ImageField(default="default.png", upload_to="patients/%Y/%m/%d", blank=True)
# other fields
def __str__(self):
return f"{self.first_name} {self.last_name}({self.username})"
class Staff(models.Model):
aadhar_number = models.BigIntegerField(verbose_name='Aadhar Number')
empCategory = models.CharField(max_length=20, blank=True, verbose_name='Employee Category')
class Meta:
abstract = True
class Patient(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
date_of_discharge = models.DateTimeField(auto_now=True)
allergies = models.TextField(blank=True, null=True)
def __str__(self):
return f"{self.user.first_name} {self.user.last_name}({self.user.username})"
class Doctor(models.Model):
DEPARTMENTS = [('Cardiologist', 'Cardiologist'),
('Dermatologists', 'Dermatologists'),
('Emergency Medicine Specialists', 'Emergency Medicine Specialists'),
('Allergists/Immunologists', 'Allergists/Immunologists'),
('Anesthesiologists', 'Anesthesiologists'),
('Colon and Rectal Surgeons', 'Colon and Rectal Surgeons')
]
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
languages = models.CharField(max_length=20)
speciality = models.CharField(max_length=20)
department = models.CharField(max_length=50, choices=DEPARTMENTS)
# patients = models.ManyToManyField(Patient, related_name='doctors')
def __str__(self):
return f"{self.user.first_name} {self.user.last_name}({self.user.username})"
class Receptionist(Staff):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
# patient = models.ManyToManyField(Patient, related_name='receptionists', blank=True)
def __str__(self):
return f"{self.user.first_name}"
class Nurse(Staff):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
class Meta:
verbose_name_plural = 'Nurses'
class Accountant(Staff):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
forms.py
class UserRegistrationForm(forms.ModelForm):
password = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Repeat Password', widget=forms.PasswordInput)
email = forms.EmailField(label='Email')
date_of_birth = forms.DateField(widget=forms.widgets.DateInput(attrs={'type': 'date'}))
class Meta:
# gives current active model either Custom User or default User model
model = get_user_model()
fields = ['username', 'first_name', 'last_name', 'email',
'date_of_birth', 'photo', 'mobile_num', 'gender',
'father_name', 'mother_name', 'blood_group', 'marital_status',
'address1', 'address2', 'city', 'zipcode', 'state'
]
exclude = ['groups', 'superuser_status',
'is_staff', 'is_superuser', ]
def clean_password2(self):
cd = self.cleaned_data
if cd['password'] != cd['password2']:
raise forms.ValidationError("Passwords don't match")
return cd['password2']
class PatientRegistrationForm(forms.ModelForm):
class Meta:
model = Patient
fields = ['allergies']
exclude = ['user', ]
views.py
class UserRegistrationMixin(TemplateResponseMixin, View):
form_class = UserRegistrationForm
template_name = 'accounts/register.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['user_form'] = self.form_class
return context
def get(self, request):
user_form = self.form_class
return self.render_to_response({'user_form':user_form})
def post(self, request):
user_form = self.form_class(data=request.POST, files=request.FILES)
if user_form.is_valid():
new_user = user_form.save(commit=False)
password = user_form.cleaned_data['password']
new_user.set_password(password)
new_user.save()
messages.success(request, f'New user "{new_user}" created!')
return self.render_to_response({'user_form':user_form})
class PatientRegistrationView(UserRegistrationMixin, CreateView):
profile_form_class = PatientRegistrationForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['profile_form'] = self.profile_form_class
return context
def get(self, request):
profile_form = self.profile_form_class
return self.render_to_response({'profile_form':profile_form})
def post(self, request):
profile_form = self.profile_form_class(data=request.POST, files=request.FILES)
if profile_form.is_valid():
# Patient.objects.create()
profile = profile_form.save(commit=False)
profile.user = new_user
profile.save()
messages.success(request, f'Profile for user "{new_user}" created!')
return self.render_to_response({'profile_form':profile_form})
我正在尝试分离用于注册用户和为每个用户创建配置文件的通用逻辑,即 UserRegistrationMixin
具有创建用户的逻辑,而 PatientRegistrationView
将创建患者的配置文件及其权限。但是当我从 UserRegistrationMixin
继承时,user_form 不显示。我对 Django 的 GCBV 没有太多经验。提前致谢。
问题出在您的 get
方法上。 get_context_data
没有调用。可以查看View
的get
方法 class:
def get(self, request, *args, **kwargs):
"""Handle GET requests: instantiate a blank version of the form."""
return self.render_to_response(self.get_context_data())
您可以调用 context = self.get_context_data()
并将 context
传递给 render_to_response
。
我在医院管理系统上工作,有 5-6 种不同类型的用户,如患者、医生、护士、会计师、接待员等。我使用 AbstractUser
扩展了用户模型,它具有所有用户的公共字段,如 DoB、地址等。
models.py
class User(AbstractUser):
# user_type = models.CharField(choices=USER_TYPES, default='patient', max_length=20)
date_of_birth = models.DateField(blank=True, null=True, validators=[validate_future_date])
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+9199999999'. Up to 15 digits allowed.")
mobile_num = models.CharField(max_length=15, validators=[phone_regex])
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
date_joining = models.DateTimeField(auto_now_add=True)
photo = models.ImageField(default="default.png", upload_to="patients/%Y/%m/%d", blank=True)
# other fields
def __str__(self):
return f"{self.first_name} {self.last_name}({self.username})"
class Staff(models.Model):
aadhar_number = models.BigIntegerField(verbose_name='Aadhar Number')
empCategory = models.CharField(max_length=20, blank=True, verbose_name='Employee Category')
class Meta:
abstract = True
class Patient(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
date_of_discharge = models.DateTimeField(auto_now=True)
allergies = models.TextField(blank=True, null=True)
def __str__(self):
return f"{self.user.first_name} {self.user.last_name}({self.user.username})"
class Doctor(models.Model):
DEPARTMENTS = [('Cardiologist', 'Cardiologist'),
('Dermatologists', 'Dermatologists'),
('Emergency Medicine Specialists', 'Emergency Medicine Specialists'),
('Allergists/Immunologists', 'Allergists/Immunologists'),
('Anesthesiologists', 'Anesthesiologists'),
('Colon and Rectal Surgeons', 'Colon and Rectal Surgeons')
]
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
languages = models.CharField(max_length=20)
speciality = models.CharField(max_length=20)
department = models.CharField(max_length=50, choices=DEPARTMENTS)
# patients = models.ManyToManyField(Patient, related_name='doctors')
def __str__(self):
return f"{self.user.first_name} {self.user.last_name}({self.user.username})"
class Receptionist(Staff):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
# patient = models.ManyToManyField(Patient, related_name='receptionists', blank=True)
def __str__(self):
return f"{self.user.first_name}"
class Nurse(Staff):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
class Meta:
verbose_name_plural = 'Nurses'
class Accountant(Staff):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
forms.py
class UserRegistrationForm(forms.ModelForm):
password = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Repeat Password', widget=forms.PasswordInput)
email = forms.EmailField(label='Email')
date_of_birth = forms.DateField(widget=forms.widgets.DateInput(attrs={'type': 'date'}))
class Meta:
# gives current active model either Custom User or default User model
model = get_user_model()
fields = ['username', 'first_name', 'last_name', 'email',
'date_of_birth', 'photo', 'mobile_num', 'gender',
'father_name', 'mother_name', 'blood_group', 'marital_status',
'address1', 'address2', 'city', 'zipcode', 'state'
]
exclude = ['groups', 'superuser_status',
'is_staff', 'is_superuser', ]
def clean_password2(self):
cd = self.cleaned_data
if cd['password'] != cd['password2']:
raise forms.ValidationError("Passwords don't match")
return cd['password2']
class PatientRegistrationForm(forms.ModelForm):
class Meta:
model = Patient
fields = ['allergies']
exclude = ['user', ]
views.py
class UserRegistrationMixin(TemplateResponseMixin, View):
form_class = UserRegistrationForm
template_name = 'accounts/register.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['user_form'] = self.form_class
return context
def get(self, request):
user_form = self.form_class
return self.render_to_response({'user_form':user_form})
def post(self, request):
user_form = self.form_class(data=request.POST, files=request.FILES)
if user_form.is_valid():
new_user = user_form.save(commit=False)
password = user_form.cleaned_data['password']
new_user.set_password(password)
new_user.save()
messages.success(request, f'New user "{new_user}" created!')
return self.render_to_response({'user_form':user_form})
class PatientRegistrationView(UserRegistrationMixin, CreateView):
profile_form_class = PatientRegistrationForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['profile_form'] = self.profile_form_class
return context
def get(self, request):
profile_form = self.profile_form_class
return self.render_to_response({'profile_form':profile_form})
def post(self, request):
profile_form = self.profile_form_class(data=request.POST, files=request.FILES)
if profile_form.is_valid():
# Patient.objects.create()
profile = profile_form.save(commit=False)
profile.user = new_user
profile.save()
messages.success(request, f'Profile for user "{new_user}" created!')
return self.render_to_response({'profile_form':profile_form})
我正在尝试分离用于注册用户和为每个用户创建配置文件的通用逻辑,即 UserRegistrationMixin
具有创建用户的逻辑,而 PatientRegistrationView
将创建患者的配置文件及其权限。但是当我从 UserRegistrationMixin
继承时,user_form 不显示。我对 Django 的 GCBV 没有太多经验。提前致谢。
问题出在您的 get
方法上。 get_context_data
没有调用。可以查看View
的get
方法 class:
def get(self, request, *args, **kwargs):
"""Handle GET requests: instantiate a blank version of the form."""
return self.render_to_response(self.get_context_data())
您可以调用 context = self.get_context_data()
并将 context
传递给 render_to_response
。