简体   繁体   中英

Add foreign key children to model form in Django

I have the following Django models:

class Contact(models.Model):
    id #primary key
    #Other contact info

class ContactType(models.Model):
    contacttype_choices=(('Primary', 'Primary'),
                         ('Billing', 'Billing'),
                         ('Business', 'Business'),
                         ('Technology', 'Technology'))
    contact=models.ForeignKey(Contact)
    type=models.CharField(choices=contacttype_choices, max_length=30)
    class Meta:
        unique_together=('contact', 'type')

So any contact object can have up to four contact types, with each type either being present or absent. I would like to make a Model Form for Contact with a multiple choice field for contact type. How can I populate this contact type field with the existing values when I construct the Contact form with a Contact instance?

Edit: To clarify, I want one checkbox to be created for each of those four choices, and if the form is instantiated with a model instance, then I want the checkboxes to be checked for each of the related objects that exists, similar to what happens automatically with the rest of the fields.

I would probably structure the models as such, so I can choose which contact type when creating/editing the Contact. If ContactType is related as a ManyToMany, we automatically get a ModelMultpleChoiceField in the ModelForm, and all we need to do is use the CheckboxSelectMultiple widget to get the output you're looking for.

When we pass an instance of Contact to the ContactForm, Django will bind any pre-selected ContactType choices and check the checkboxes for us.

Setting the title of each ContactType to unique does the same as unique_together on the contact and contact_type.

#models.py
class Contact(models.Model):
    #other fields
    contact_types = models.ManyToMany(ContactType)

class ContactType(models.Model):
    title = models.CharField(max_length=20, unique=true)

#forms.py
class ContactForm(forms.ModelForm):
    class Meta:
        model = Contact

    def __init__(self, *args, **kwargs):
        super(ContactForm, self).__init__(*args, **kwargs)
        self.fields['contact_types'].widget = forms.CheckboxSelectMultiple()

Have you tried something like this?

class ContactForm(forms.ModelForm):
    class Meta:
        model = Contact
    def __init__(self, *args, **kwargs):
        super(ContactForm, self).__init__(*args, **kwargs)
        self.fields['contacttypes'] = forms.MultipleChoiceField(
            choices = CONTACT_TYPE_CHOICES, 
            label = "contact type",
            widget = CheckBoxSelectMultiple
        )

contact = Contact.objects.get(pk=1) # or whatever
types = ContactType.objects.filter(contact = contact)
form = ContactForm(instance=contact, initial={'contacttypes' : types})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM