Изменение кверисета внешнего ключа в Django создает CBV
У меня есть 2 группы по 5 сотрудников. В каждой группе один из сотрудников является руководителем этой группы.
В представлении создания, после заполнения поля supervisor, я хотел бы, чтобы поле внешнего ключа employee показывало только тех сотрудников, которые принадлежат этому руководителю.
Хотелось бы, чтобы соответствующие сотрудники отображались в зависимости от пользователя (руководителя) без необходимости сначала заполнять поле руководителя.
Я пробовал использовать модельные формы, чтобы попытаться соответствующим образом изменить набор запросов к полю внешнего ключа сотрудника, но, очевидно, безрезультатно. Пожалуйста, помогите!
Код выглядит следующим образом:
class Instruction(models.Model):
supervisor = models.ForeignKey(
Profile, on_delete=models.CASCADE,
related_name="supervisorinstructions"
)
employee = models.ForeignKey(
Profile, on_delete=models.CASCADE,
related_name="employeeinstructions"
)
instruction = models.CharField(max_length=300)
def __str__(self):
return f"{self.instruction}"
def get_absolute_url(self):
return reverse("myapp:instructiondetail", kwargs={"pk": self.pk})
class InstructionCreate(CreateView):
model = models.Instruction
fields = [
"supervisor",
"employee",
"instruction",
]
template_name = "myapp/instruction_create_form.html"
Пока вы не обновите свой вопрос, я буду считать, что у вас есть модель, подобная этой:
class Employee(models.Model):
# some fields not related to the current question
supervisor = models.ForeignKey(
'Employee', on_delete=models.CASCADE,
related_name="employee_direct_reports"
)
Теперь, если у вас есть объект Employee
с именем supervisor
, вы можете сделать supervisor.employee_direct_reports
, чтобы получить набор объектов Employee
, начальником которых является supervisor
. Для ваших целей вы, вероятно, захотите отправить это в контексте вашей формы, чтобы заполнить выпадающий список.
Проблема заключалась в том, чтобы помешать начальнику давать указания чужим подчиненным.
Поскольку я новичок в Django, я сосредоточился на методологии, в которой я еще недостаточно хорош, и забыл сосредоточиться на желаемом результате.
Использование приведенного ниже кода достигает цели, указанной в первом предложении:
class Instruction(models.Model):
employee = models.OneToOneField(Profile, on_delete=models.CASCADE, blank=True, null=True,
related_name="employeeinstructions")
supervisor = models.ForeignKey(Profile, on_delete=models.CASCADE, blank=True, null=True,
related_name="supervisorinstructions")
class InstructionCreateForm(ModelForm):
class Meta:
model = models.Instruction
fields = ["supervisor", "employee", "instruction"]
def clean(self):
cleaned_data = super(InstructionCreateForm, self).clean()
supervisor = cleaned_data.get('supervisor')
employee = cleaned_data.get('employee')
if employee != models.Profile.objects.filter(employee=employee, supervisor=supervisor):
self.add_error(None, ValidationError('The employee is not a subordinate of this supervisor.'))
return cleaned_data
class InstructionCreate(CreateView):
model = models.Instruction
template_name = "internalcontrol/instruction_create_form.html"
form_class = forms.InstructionCreateForm