How can I limit the available choices for a foreign key field in a django modelformset?
Application: This is a workshop proposal system for a conference. A user can create presenters and workshops, and link them together. Each user should only have access to the presenters and workshops that s/he created/owns.
# Models:
class Workshop(models.Model):
name = models.CharField(max_length=140, db_index=True)
presenters = models.ManyToManyField("Presenter", through="WorkshopPresenter")
owner = models.ForeignKey(User)
class Presenter(models.Model):
name = models.CharField(max_length=140, db_index=True)
owner = models.ForeignKey(User)
class WorkshopPresenter(models.Model):
workshop = models.ForeignKey("Workshop")
presenter = models.ForeignKey("Presenter")
cardinality = models.IntegerField()
To link presenters to workshops, the user is directed to a workshop-specific page, containing a modelformset for WorkshopPresenter
. Workshop and cardinality are set by the view after the formset is filled out, so the user only sees a list of dropdowns with possible presenter names.
Image of the association page
Question: How can I make it so the presenter dropdowns on this association page only contain presenters who are owned by the current user? The dropdowns should only contain the results of Presenter.objects.filter(owner__exact=request.user)
. Currently they contain all presenters.
# View snippet that creates the formset:
workshop = Workshop.objects.filter(owner__exact=request.user).get(id=workshop_id)
MyWorkshopPresenterFormSet = modelformset_factory(WorkshopPresenter,
formset=WorkshopPresenterFormSet,
extra=5,
开发者_运维问答 exclude = ("workshop","cardinality"))
formset = MyWorkshopPresenterFormSet(request.POST or None,
queryset=workshop.workshoppresenter_set.all())
WorkshopPresenterFormSet
just extends BaseModelFormSet
and does some custom validation, nothing fancy.
I've seen some solutions out there that work for regular forms, but nothing to work with modelformsets.
You can dynamically change the queryset on a form using functional methods (curry), closures, or callbacks. See all three methods in the first three answers to "passing custom form parameters to formset."
Also see James Bennetts post "So you want a dynamic form" for a nice in-depth discussion of the closure method.
精彩评论