Tuesday, 16 March 2021

User Form not showing django class based views

I am working on Hospital Management System and there are 5-6 different types of users like Patient, Doctor, Nurse, Accountant, Receptionist, etc. I've extended the User model using AbstractUser which has common fields for all users like DoB, address, etc. 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})

I am trying to separate common logic for registering users and creating profiles for each user i.e. UserRegistrationMixin has logic to create a user and PatientRegistrationView will create a patient's profile and its permissions. But when I inherit from UserRegistrationMixin, user_form doesn't show. I don't have much experience in Django's GCBV. Thanks in advance.



from User Form not showing django class based views

No comments:

Post a Comment