Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Form with a one-to-many relationship

Tags:

I have a form in Django called PersonForm this forms model has a one-to-many relationship with Car. When displaying the PersonForm just like in the Django Admin I would like to allow my users to select/deselect from a list of Cars etc. Is this possible? I'm looking for information on where to start.

This is what I have so far for the PersonForm:

class PersonForm(forms.ModelForm):

    class Meta:
        model = Person
        fields = ('description',)

The Models:

class Person(models.Model):
    description = models.CharField(max_length="150")



class Car(models.Model):
    make = models.CharField(max_length="25")
    owner = models.ForeignKey('Person', related_name="Car")

So in the person form I need to show a list of cars that person is the owner of an allow selecting/deselecting of them. I'm assuming I can do this in the form i.e. using something like the related name.

like image 638
Prometheus Avatar asked Jan 10 '14 14:01

Prometheus


2 Answers

Sounds like you want an inline model form. This give you the ability to add/remove Car objects from a Person within the Person form.

That previous link was for inlinemodeladmin. This next link is for an inline form: https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#modelforms-factory

like image 64
ptr Avatar answered Oct 06 '22 01:10

ptr


I didn't have any chance with inline formset, so i would suggest to override your save method of the model, i feel it's more DRY:

class PersonForm(forms.ModelForm):
    # add a field to select a car
    car = forms.ModelChoiceField(car.objects.all())

    class Meta:
        model = Person
        fields = ('description', 'car')

     def save(self, commit=True):
        instance = super().save(commit)
        # set Car reverse foreign key from the Person model
        instance.car_set.add(self.cleaned_data['car']))
        return instance
like image 45
Guillaume Lebreton Avatar answered Oct 05 '22 23:10

Guillaume Lebreton