用户表单未显示基于 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 没有调用。可以查看Viewget方法 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