У меня есть форма, набор запросов которой зависит от request.user, и чье начальное значение зависит от ключа сеанса. Основными моделями являются Пользователь (небольшая модификация модели пользователя по умолчанию) и Учетная запись, между которыми существует отношение многие ко многим. Форма позволяет пользователю изменить учетную запись, которую он просматривает, и этот выбор должен сохраняться, пока пользователь перемещается по сайту. Форма отлично работает, когда создается в одном представлении и передается в один шаблон, но я хочу, чтобы форма отображалась в верхней панели навигации, чтобы пользователь мог изменять учетные записи из любого места.
Вот форма:
class ChangeAccountContextForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
self.current_account_id = kwargs.pop('account_id')
super(ChangeAccountContextForm, self).__init__(*args, **kwargs)
self.fields['account_choices'].queryset = self.user.accounts.all()
try:
self.fields['account_choices'].initial = Account.objects.get(id=self.current_account_id)
except(Account.DoesNotExist):
self.fields['account_choices'].initial = None
#queryset and initial are set to None, because they are assigned dynamically in the constructor (see above)
account_choices = forms.ModelChoiceField(queryset=None, initial=None, label='Account:', widget=forms.Select(attrs={'onChange':'this.form.submit()', 'class': 'custom-select mr-sm-2 ml-2'}), required=True )
class Meta:
model = User
fields = ['account_choices']
А вот существующее представление, в котором используется форма:
@login_required
def welcome_view(request):
user = request.user
context = {}
accounts = user.accounts.all().order_by('account_name')
context['accounts'] = accounts
context['num_accounts'] = len(accounts)
try:
account_id = request.session['current_account_id']
except (KeyError):
account_id = None
if request.method == 'POST':
form = ChangeAccountContextForm(request.POST, user=user, account_id=account_id)
context['form'] = form
if form.is_valid():
new_account_context = form.cleaned_data['account_choices']
request.session['current_account_name'] = new_account_context.account_name
request.session['current_account_id'] = new_account_context.id
else:
form = ChangeAccountContextForm(user=user, account_id=account_id)
context['form'] = form
return render(request, 'welcome.html', context)
(Кстати, ключи сессии установлены когда пользователь входит в систему.)
Учитывая зависимость от request.user и переменных, хранящихся в сеансе, я не уверен, как включить форму на каждой странице, не восстанавливая форму в каждом представлении, как показано выше. , Полагаю, это сработает, но я уверен, что подход должен быть более DRY.