I have a ManyToMany field with a relationship model. I want a formset, filtered on one of the keys, which shows a form for each of the other keys.
My guess is that a custom manager on the relationship model is the key to solving this problem. The manager would return "phantom" instances initialized with the appropriate ForeignKey when no real instance was in the database. I'm just don't know how to make a manager add "phantom" instances when it seems designed to filter out existing ones.
I'm hoping an example is worth 1K words.
Say I want my users to be able to rate albums. I would like to display a formset with a form for all albums by the selected band. Example models & view
from django.contrib.auth.models import User
from django.db import models
class Band(models.Model):
name = models.CharField(max_length=30)
def __unicode__(self):
return self.name
class Album(models.Model):
name = models.CharField(max_length=30)
band = models.ForeignKey(Band)
ratings = models.ManyToManyField(User, through="Rating")
def __unicode__(self):
return self.name
class Rating(models.Model):
user = models.ForeignKey(User)
album = models.ForeignKey(Album)
rating = models.IntegerField()
def __unicode__(self):
return "%s: %s" % (self.user, self.album)
# views.py
from django.forms.models import modelformset_factory
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template.context import RequestContext
from models import Band, Rating
RatingFormSet = modelformset_factory(Rating, exclude=('user',), extra=1)
def update(request):
user = request.user
band = Band.objects.all()[0]
formset = RatingFormSet(request.POST or None,
queryset=Rating.objects.filter(album__band=band,
user=user))
if formset.is_valid():
objects = formset.save(commit=False)
print "saving %d objects" % len(objects)
for obj in objects:
obj.user = user
obj.save()
return HttpResponseRedirect("/update/")
return render_to_response("rating/update.html",
{'formset': formset, 'band':band},
context_instance=RequestContext(request))
The problem is it only shows forms for existing relationship instances. How can I get an entry for all albums.
Thanks.