Отображение только определенных опций в выпадающем списке формы django
День добрый, я создаю сайт для управления данными для программного обеспечения с помощью django. Пользователи на сайте связаны с подразделениями (регионами) в модели подразделений через поле многие-ко-многим. Все фактические данные связаны с профилями, которые принадлежат подразделениям. Пользователи подразделения могут редактировать профили, принадлежащие подразделению, но не другие. Моя проблема связана с формами для создания профилей.
Прилагается изображение формы. Поле "Подразделение" показывает все подразделения, зарегистрированные на сайте, но я хочу, чтобы оно показывало только те, членом которых является вошедший пользователь. Например, этот пользователь является членом только 'VATPAC', поэтому он должен показывать только это в качестве опции для выбора. Прилагаю весь соответствующий код.
Forms.py
class ProfileForm(ModelForm):
class Meta:
model = models.Profile
fields = ('division', 'name')
widgets = {
'division': forms.Select(attrs={'class':'form-control'}),
'name': forms.TextInput(attrs={'class':'form-control'})
}
views.py
def AddProfile(request):
submitted = False
if request.method == "POST":
form = forms.ProfileForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('profile?submitted=true')
else:
form = forms.ProfileForm
if 'submitted' in request.GET:
submitted = True
return render(request,'profiles/create/create_profile.html', {'form': form, 'submitted': submitted})
models.py
class Profile(models.Model):
division = models.ForeignKey(Division, on_delete=models.CASCADE)
name = models.CharField(max_length=255)
def __str__(self):
return self.name
models.py (foreignkey для разделения)
class Division(models.Model):
division_id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=6)
users = models.ManyToManyField(User)
def __str__(self):
return self.name
Вы захотите переопределить функцию __init__()
вашей формы, передать текущего пользователя и соответствующим образом отфильтровать набор запросов подразделения.
class MyForm(forms.ModelForm):
def __init__(self, user=None, *args, **kwargs): # note the additional user param
self.divisions = Division.objects.filter(users=user)
super(MyForm, self).__init__(*args, **kwargs)
self.fields['division'].queryset = self.divisions
Когда вы вызываете свою форму, не забудьте передать request.user
в качестве именованного параметра.
Учтите, что вам потребуется много фильтрации в вашем приложении, чтобы убедиться, что пользователи не могут взаимодействовать с подразделениями, к которым они не имеют отношения. У вас целочисленные первичные ключи, поэтому для пользователя не составит труда угадать или хотя бы попытаться получить доступ к другим подразделениям путем перечисления. Приведенный выше код не помешает кому-то изменить значение элемента <select>
вашего шаблона и отправить его. Вам нужно будет очистить ввод перед сохранением формы.