Вам нужно поместить первые две строки из определения класса ProjectsForm
в метод его инициализации и немного их изменить.
class ProjectsForm(forms.ModelForm):
name = forms.ModelChoiceField(queryset=Employee.objects.all(),
empty_label="(Select a Project)", required=True)
class Meta:
model = Projects
def __init__(self, user, *args, **kwargs):
super(self, ProjectsForm).init(*args, **kwargs)
employee = get_object_or_404(Employee, user=user)
self.fields['name'].queryset = employee.projects_set.all()
Теперь немного объяснений. Надеюсь, кто-нибудь найдет это полезным.
В своем первоначальном определении ProjectsForm
вы пытаетесь получить проекты сотрудника, когда ваш класс определен . Но это происходит после компиляции вашего файла forms.py, что происходит редко (например, при изменении кода). Кроме того, у вас, конечно, нет данных, необходимых для фильтрации проектов, то есть на этом этапе нет объекта user
.
Вместо этого вам нужно делать это каждый раз, когда класс инициализируется . Инициализация в Python происходит специальным методом __init__()
. Например, когда вы делаете что-то вроде
form = ProjectsForm(data=request.POST)
По вашему мнению, ProjectsForm.__init__(data=request.POST)
вызывается для инициализации ProjectsForm
в экземпляре.
Итак, в нашем новом определении мы требуем, чтобы новый аргумент (пользователь) передавался в форму при ее создании. Таким образом, вы можете сделать что-то подобное на ваш взгляд:
form = ProjectsForm(request.user, data=request.POST)
В новом методе инициализации сначала мы вызываем метод инициализации родительского класса (который выполняет некоторые внутренние функции django и в любом случае должен вызываться), затем используем аргумент user
, чтобы получить связанного сотрудника, а затем назначаем набор запросов с проекты этого сотрудника в поле name
.
Извините, если я слишком многословен.
Смотри также: