[Answered ]-How to use choices of a Select field of a form, when defined in the view in Django?

1👍

The form field of a ForeignKey is a ModelChoiceField [Django-doc], this neecds the primary key of the item to work with, not the name of a category. You thus try to do too much yourself, and thus invalidated the data of the form field.

I suggest that you let the form handle it and specify the queryset when necessary:

class CreateExpanseForm(forms.ModelForm):
    def __init__(self, *args, user=None, **kwargs):
        super().__init__(*args, **kwargs)
        if user is not None:
            self.fields['user'].queryset = user.current_group.user_set.all()
            self.fields[
                'category'
            ].queryset = user.current_group.category_set.all()

    class Meta:
        model = Expanses
        fields = ['date', 'amount', 'category', 'user', 'comment']
        widgets = {
            'date': DateInput(
                attrs={
                    'placeholder': 'Date',
                    'class': 'form-input',
                    'type': 'date',
                }
            ),
            'amount': TextInput(
                attrs={
                    'placeholder': 'Amount',
                    'class': 'form-input',
                    'type': 'text',
                }
            ),
            'category': Select(
                attrs={
                    'placeholder': 'Category',
                    'class': 'form-select',
                    'type': 'text',
                }
            ),
            'user': Select(
                attrs={
                    'placeholder': 'user',
                    'class': 'form-select',
                    'type': 'text',
                }
            ),
            'comment': TextInput(
                attrs={
                    'placeholder': 'comment',
                    'class': 'form-input',
                    'type': 'text',
                }
            ),
        }

In the view you can then just pass the logged in user:

from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect


@login_required
def summary_view(request):
    form = CreateExpanseForm(user=request.user)
    if request.method == 'POST':
        if 'createExpanse' in request.POST:
            form = CreateExpanseForm(
                request.POST, request.FILES, user=request.user
            )
            if form.is_valid():
                form.instance.group = request.user.current_group
                expanse = createExpanseForm.save()
                return redirect('name-of-some-view')

    context = {'createExpanseForm': form}
    return render(request, 'app/summary.html', context)

Note: Functions are normally written in snake_case, not PascalCase, therefore it is
advisable to rename your function to summary_view, not SummaryView.


Note: You can limit views to a view to authenticated users with the
@login_required decorator [Django-doc].


Note: In case of a successful POST request, you should make a redirect
[Django-doc]

to implement the Post/Redirect/Get pattern [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.

Leave a comment