Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing Many to Many "through" relation fields in Formsets

My Models:

class End_User(models.Model):
    location = models.ForeignKey(Location) 
    first_name = models.CharField(max_length=70, blank=True, null=True)
    email_address = models.CharField(max_length=70, blank=True, null=True)

class Phone_Client(models.Model):
    end_user = models.ManyToManyField(End_User)
...
    extensions = models.CharField(max_length=20)

class Line(models.Model):
    phone_client = models.ManyToManyField(Phone_Client, through='Phone_Line' )
    ....
    voicemail = models.BooleanField(default=False)  

class Phone_Line(models.Model):
    phone_client = models.ForeignKey(Phone_Client)
    line = models.ForeignKey(Line)
    line_index = models.IntegerField()

So basically One end user can have many phones, a phone can have many Lines, related through Phone_line.

My page need to have all these objects editable and new instances created runtime for Phone_Clients and Line all in the same page. Currently I am creating a simple End_User model form and modelformset_factory objects for Phone_Client and Lines. Since a phone can have many lines, each phone form in the phone_formset can have a line formset object. I am currently doing something like this

end_user = End_User.objects.get(pk=user_id)
user_form = End_UserForm(instance=end_user)

Phone_ClientFormSet = modelformset_factory(Phone_Client,form=PartialPhone_ClientForm,  extra=0, can_delete=True)

phone_clients_formset = Phone_ClientFormSet(queryset=end_user.phone_client_set.all(), prefix='phone_client')

all_lines = modelformset_factory(Line, form=PartialLineForm, extra=0, can_delete=True)

phone_clients = end_user.phone_client_set.all()

client_lines_formsets = {}
for phone in phone_clients:
    client_lines_formsets[phone.id] = all_lines(queryset=phone.line_set.all(), prefix='phone_client_'+str(phone.id))

I am using this list to display lines belonging to a phone_client in the template using formsets.

I have the following question, on the models

  1. Can I use inline_formset factory to handle many to many relation containing a through class? if so how do I do that for the Phone_Client, Line and Phone_Line through relation?

  2. I need to display the line_index for a given phone, line combination, how do I do that in template? I have looked at
    How do I access the properties of a many-to-many "through" table from a django template? I do not want to only display, but bind the value to the phone, line combination if possible in the line or phone formset, such that if user changes the index, I can save that in the data base while posting the formset data.

I am new to django so any help is really appreciated. Thanks!!

like image 736
akotian Avatar asked Jun 13 '12 18:06

akotian


1 Answers

As you're probably aware, you can't edit many-to-many relationships with inline formsets. You can, however, edit the through model. So for your inline formset, you just need to set the model to the through model, e.g.:

inlineformset_factory(Phone_Client, Line.phone_client.through)

line_index will actually be a visible field on the inline form, so you really don't have to do anything. If someone changes the index, it'll be saved when the inline forms are saved, just like the rest of the fields.

like image 173
Chris Pratt Avatar answered Oct 18 '22 14:10

Chris Pratt