1

I'm trying to create a view that handles two forms with models related by a ForeignKey. The purpose of this form is to add a Bedroom and the Lights related to that Bedroom on the same page.

#views.py
def add_bedroom(request, pk):
    get_property_id = pk
    data = {'property':get_property_id}
    property_reference = Property.objects.get(pk=get_property_id)
    if request.method == 'POST':

        bedroom_form = AddBedroomForm(request.POST, request.FILES, initial=data)
        lighting_form = LightingBedroomAddForm(request.POST)

        if bedroom_form.is_valid() and lighting_form.is_valid():
            bedroom = bedroom_form.save()
            add_lighting = lighting_form.save(commit=False)
            add_lighting.bedroom = bedroom
            add_lighting.save()

            return HttpResponseRedirect(reverse('properties:property_detail', args=[pk]))
    else:
        print('Error')
        bedroom_form = AddBedroomForm(initial=data)
        lighting_form = LightingBedroomAddForm()

    context = {
        'add_bedroom_form':bedroom_form,
        'add_lighting_form':lighting_form,
        'title':"Add Bedroom",
        'reference':property_reference,
    }
    return render(request, 'properties/add-bedroom.html', context)

For some reason it doesn't work and my guess is that when I assign this add_lighting.bedroom = bedroomit doesn't get the id value. I get the POST printed but it just reloads the page(I don't have validation errors). What am I doing wrong here? I've checked this Link1 and this Link2

#models.py
class Bedroom(models.Model):
    type = models.CharField(db_column='Type', choices=BEDROOM_TYPE_CHOICES, max_length=50)
    bed_dimensions = models.CharField(db_column='Bed_Dimension', choices=BED_DIMENSION_CHOICES, max_length=30)
    image = models.ImageField(null=True, blank=True)
    ensuite = models.BooleanField(default=False)
    notes = models.CharField(db_column='Notes', max_length=500, blank=True, null=True)  # Field name made lowercase.
    property = models.ForeignKey(Property, null=False, on_delete=models.CASCADE, related_name='bedroom')

    def __str__(self):
        return str(self.pk)

class LightingBedroom(models.Model):
    type = models.CharField(db_column='Type', choices=LIGHTING_TYPE_CHOICES, max_length=30)
    bulb_type = models.CharField(db_column='Bulb_Type',  max_length=30)
    bedroom = models.ForeignKey(Bedroom, on_delete=models.CASCADE)

#forms.py
class AddBedroomForm(forms.ModelForm):
    property = forms.ModelChoiceField(queryset=Property.objects.all(),widget=forms.Select(
    attrs={
    'class':'form-control custom-select',
    'id':'disabledSelect',
    }))
    type = forms.CharField(widget=forms.Select(choices=BEDROOM_TYPE_CHOICES,
    attrs={
    'class':'form-control custom-select',
    'id':'type',
    }))
    bed_dimensions = forms.CharField(widget=forms.Select(choices=BED_DIMENSION_CHOICES,
    attrs={
    'class':'form-control custom-select',
    'id':'type',
    }))
    ensuite = forms.BooleanField(required=False,widget=forms.CheckboxInput(
    attrs={
    'class':'custom-control-input',
    'type':'checkbox',
    'id':"customCheck1",
    }))
    notes = forms.CharField(required=False, widget=forms.Textarea(
    attrs={
    'class':'form-control',
    'rows':'5',
    'id':'pdesc',
    'placeholder':"Add Notes",
    }))
    image = forms.ImageField(required=False, widget=forms.FileInput(
    attrs={
    'id':'form-input-file-now',
    'class':'dropify',
    }))

    class Meta:
        model = Bedroom
        fields = ('type','bed_dimensions','ensuite','notes','image','property')

class LightingBedroomAddForm(forms.ModelForm):
    type = forms.CharField(widget=forms.Select(choices=LIGHTING_TYPE_CHOICES,
    attrs={
    'class':'form-control custom-select',
    'id':'type',
    }))
    bulb_type = forms.CharField(widget=forms.TextInput(
    attrs={
    'class':'form-control',
    'type':'text',
    'id':"pname",
    'placeholder':"Enter Name",
    }))
    bedroom = forms.ModelChoiceField(queryset=Bedroom.objects.all(),widget=forms.Select(
    attrs={
    'class':'form-control custom-select',
    'id':'disabledSelect',
    }))

    class Meta:
        model = LightingBedroom
        fields = ('type','bulb_type','bedroom')
Luis Silva
  • 173
  • 13
  • 1
    Is the indentation as you show here? Why do you print 'Error' in the GET case? Also, are you showing the errors in your template so that if there are validation errors you actually see them? (`{{ add_bedroom_form.errors }}` and `{{ add_lighting_form.errors }}`). It's not clear what you're saying about what's actually happening: "I get the POST printed" what do you mean by that? How do you check that you don't have validation errors? – dirkgroten Sep 09 '19 at 11:59
  • Also you're not showing your forms. – dirkgroten Sep 09 '19 at 11:59
  • @dirkgroten Thanks for your help. I've included the forms.py, I also added the validation errors in the template so I could see what was wrong. I get `This field is required.` on the bedroom field of the LightingBedroom form. The indentation it's exactly like here. – Luis Silva Sep 09 '19 at 12:13
  • 1
    You should just remove the `bedroom` field from your form (both from `fields` and the field itself), since you're assigning it yourself. – dirkgroten Sep 09 '19 at 13:03
  • Thanks you! I've removed it like you said and it's working perfectly. – Luis Silva Sep 09 '19 at 13:38

0 Answers0