Reputation: 776
I have a models.py like this:
class Work(models.Model):
[...]
instrumentations = models.ManyToManyField('Instrument', 'Percussion',
through='Instrumentation',
blank=True)
class Instrument(models.Model):
name = models.CharField(max_length=100)
family = models.CharField(max_length=20, default='')
class Percussion(models.Model):
name = models.CharField(max_length=100)
class Instrumentation(models.Model):
players = models.IntegerField()
work = models.ForeignKey(Work, on_delete=models.CASCADE)
instrument = models.ForeignKey(Instrument, on_delete=models.CASCADE)
percussion = models.ManyToManyField(Percussion, blank=True, default=None) # Ideally percussions should be in the Instrument model with family 'percussion', though I don't know how to make Django like that. A separate model is a good workaround for me.
My view:
def work_edit_view(request, id=id):
InstrumentFormSet = inlineformset_factory(Work, Work.instrumentations.through, extra=1, can_delete=True,
fields=('instrument', 'percussion', 'players', 'work'), widgets={
'work': forms.HiddenInput(),
'players': forms.NumberInput(attrs={'placeholder': 'Number of players'})
form_details = InstrumentFormSet(request.POST or None, instance=obj_work, initial=[{'work' : obj_work.id}], prefix='instruments')
})
The data gets saved correctly in my input form, so that's not an issue. My problem is visualising the information in my template. I can only access the 'instrument', not my 'percussion' or my 'players'. What am I doing wrong?
{% for instrument in work.instrumentations.all %}
{{ instrument }} {{ instrument.players }} # only instrument is output.
{% for percussion in instrument.percussion.all %} # this looks to be empty.
Percussion {{ forloop.counter }} ({{ percussion.players }}) # No luck here :(
{% endfor %}
Upvotes: 1
Views: 171
Reputation: 477180
You can, but you need to access it correctly, you can access the Instrumentation
s with work.instrumentation_set
:
{% for instrumentation in work.instrumentation_set.all %}
{{ instrumentation.instrument }} {{ instrumentation.players }}
{% for percussion in instrumentation.percussion.all %}
Percussion {{ forloop.counter }} ({{ percussion.players }})
{% endfor %}
{% endfor %}
Note: that a
ManyToManyField
can not refer to multiple models. The second parameter is therelated_name
, so you set the name of the relation in reverse to'Percussion'
, which might not be ideal.
Upvotes: 1