views:

137

answers:

2
+3  Q: 

Limit choices to

I have a model named Project which has a m2m field users. I have a task model with a FK project. And it has a field assigned_to. How can i limit the choices of assigned_to to only the users of the current project?

A: 

You need to create a custom form for the admin.

Your form should contain a ModelChoiceField in which you can specify a queryset parameter that defines what the available choices are. This form can be a ModelForm.

(the following example assumes users have an FK to your Project model)

forms.py

from django import forms

class TaskForm(forms.ModelForm):
    assigned_to = forms.ModelChoiceField(queryset=Users.objects.filter(user__project=project))

    class Meta:
        model = Task

Then assign the form to the ModelAdmin.

admin.py

from django.contrib import admin
from models import Task
from forms import TaskForm

class TaskAdmin(admin.ModelAdmin):
    form = TaskForm
admin.site.register(Task, TaskAdmin)
Soviut
My users don't have a FK to my project model. But my Project model has a M2M field users.
swoei
The idea is the right one, but the code as given will not work, as the 'project' variable is undefined. The right-hand side of a queryset parameter must be an actual value or variable, not a field on the model. You actually need to override the form's `__init__` method here to get this to work.
Daniel Roseman
+1  A: 

You could do this another way, using this nifty form factory trick.

def make_task_form(project):
    class _TaskForm(forms.Form):
        assigned_to = forms.ModelChoiceField(
              queryset=User.objects.filter(user__project=project))

        class Meta:
            model = Task
    return _TaskForm

Then from your view code you can do something like this:

project = Project.objects.get(id=234)
form_class = make_task_form(project)
...
form = form_class(request.POST)
jdl2003