Zameer Ahmed
Zameer Ahmed

Reputation: 63

Multiple Django OneToOne ModelForm Validation in single Create View

I have three modelforms and I am trying to validate those forms in a single view. All forms are connected with OneToOne relation. I cannot validate subforms after main form ins same view. Tried few solutions and I guess I am doing something wrong and if someone can help I can redo it few times to understand it at my end. DoctorForm works fine but I couldn't find a suitable method to validate DoctorQualificationForm() and WorkExperienceForm(). Following is the code:

Models:

class User(AbstractUser):

    ACC_TYPE = (
        ('', ''),
        ('Doctor', 'Doctor'),
        ('Patient', 'Patient')
    )
    account_type = models.CharField(max_length=20, choices=ACC_TYPE, null=True, blank=True)
    cell_phone = models.IntegerField(null=True, blank=True)
    landline = models.IntegerField(null=True, blank=True)
    pic = models.ImageField(upload_to='profile/', null=True, blank=True)
    secondary_email = models.EmailField(null=True, blank=True)
    def __str__(self):
        return str(self.username)

    def get_absolute_url(self):
        return reverse('user:detail', kwargs={'pk':self.user.pk})


class Role(models.Model):
    LAB_ADMIN = 1
    SALES_ADMIN = 2
    SALES_EXCUTIVE = 3
    LAB_TECH = 4

    ROLE_CHOICES = (
        (LAB_ADMIN, 'Lab Admin'),
        (SALES_ADMIN, 'Sales Admin'),
        (SALES_EXCUTIVE, 'Sales Executive'),
        (LAB_TECH, 'Lab Tech'),

    )

    id = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, primary_key=True)
    doctor = models.OneToOneField('Doctor', on_delete=models.CASCADE, related_name='roles')

    def __str__(self):
        return self.id


class Doctor(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='doctor', null=True)
    about = models.TextField()
    #role = models.OneToOneField(Role, on_delete=models.CASCADE, related_name='currentrole',null=True, blank=True)
    street = models.CharField(max_length=200)
    city = models.CharField(max_length=200)
    country = models.CharField(max_length=200)
    cell_phone = models.CharField(max_length=200)
    landline = models.CharField(max_length=200)
    def __str__(self):
        return str(self.user)



    def get_absolute_url(self):
        return reverse('doctor:detail', kwargs={'pk':self.pk})

class Qualitifaction(models.Model):
    doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE,
                                          related_name='qualifications')
    course_title = models.CharField(max_length=100)
    institute_name = models.CharField(max_length=200)
    location = models.CharField(max_length=200)
    start_year = models.DateField(null=True)
    end_year = models.DateField(null=True)

    def __str__(self):
        return self.course_title


    def get_absolute_url(self):
        return reverse('doctor:detail', kwargs={'pk':self.pk})

class WorkExperience(models.Model):
    doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE,
                                        related_name='experience')
    organization_name = models.CharField(max_length=100)
    year_from = models.DateField(null=True)
    year_to = models.DateField(null=True)
    employement_role = models.CharField(max_length=200)
    industry = models.CharField(max_length=200)

    def __str__(self):
        return self.organization_name
    def get_absolute_url(self):
        return reverse('doctor:detail', kwargs={'pk':self.pk})
@receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
    if created:
        if instance.account_type=='Employee':
            profile = Employee.objects.get_or_create(user=instance)
        elif instance.account_type=='Customer':
            profile = Customer.objects.get_or_create(user=instance)

post_save.connect(update_user_profile, sender=User)

Forms:

class DoctorForm(forms.ModelForm):
    model = Doctor
    fields = ('about', 'street', 'city', 'country', 'cell_phone', 'landline',)


class DoctorQualificationForm(forms.ModelForm):
    model = Qualitifaction
    fields = ('course_title', 'institute_name', 'location', 'start_year', 'end_year')

class WorkExperienceForm(forms.ModelForm):
    model = WorkExperience
    fields = ('organization_name', 'year_from, 'year_to', 'employement_role', 'industry')

View:

def createDoctor(request):
    if request.method == 'POST':
        doctorform = DoctorForm(request.POST, instance=request.user.doctor)
        qualifications_form = DoctorQualificationForm()# not sure how to ref instance here
        workexperience_form = WorkExperienceForm()# not sure how to ref instance here
        if doctorform.is_valid() and qualifications_form.is_valid() and workexperience_form.is_valid():
            doctorform.save()
            qualifications_form.save()
            workexperience_form.save()
    else:
        doctorform = DoctorForm()
        qualifications_form = DoctorQualificationForm()
        workexperience_form = WorkExperienceForm()

    return render(request, 'doctor/create.html', {'doctorform':doctorform, 'qualifications_form':qualifications_form, 'workexperience_form':workexperience_form})

Upvotes: 0

Views: 67

Answers (1)

Mudassar Hashmi
Mudassar Hashmi

Reputation: 2899

def createDoctor(request):
    if request.method == 'POST':
        doctorform = DoctorForm(request.POST, instance=request.user.doctor)
        qualifications_form = DoctorQualificationForm(request.POST)# not sure how to ref instance here
        workexperience_form = WorkExperienceForm(request.POST)
        if doctorform.is_valid() and qualifications_form.is_valid() and workexperience_form.is_valid():
            doctor = doctorform.save()
            qualification = qualifications_form.save(commit=False)
            qualification.doctor = doctor
            qualification.save()
            work = workexperience_form.save(commit=False)
            work.doctor = doctor
            work.save()
    else:
        doctorform = DoctorForm()
        qualifications_form = DoctorQualificationForm()
        workexperience_form = WorkExperienceForm()

    return render(request, 'doctor/create.html', {'doctorform':doctorform, 'qualifications_form':qualifications_form, 'workexperience_form':workexperience_form})

Although there are number of other ways to do it. But in case you have OneToOne rel in all models you just need to use validation of single or parent model. You can reference that validation in all the children as above.

Upvotes: 1

Related Questions