Create forms that require a foreign key

Ok, I was able to solve two problems with the help of Copilot.

forms.py:

from django import forms
from .models import Problem


class ProblemForm(forms.ModelForm):
    class Meta:
        model = Problem
        fields = ['responsibility', 'summary', 'description', 'user']
        widgets = {
            'responsibility': forms.HiddenInput(),
            'user': forms.HiddenInput(),
        }

    def __init__(self, *args, **kwargs):
        responsibility = kwargs.pop('responsibility', None)
        super(ProblemForm, self).__init__(*args, **kwargs)
        if responsibility:
            self.fields['responsibility'].initial = responsibility

views.py:

def problem_create(request, id):
    related_instance = get_object_or_404(Responsibility, id=id)
    redirect_url = '/responsibility-details/' + str(id) + '/'
    if request.method == 'POST':
        problem_form = ProblemForm(request.POST, responsibility=related_instance.id)
        if problem_form.is_valid():
            problem_form.save()

            return HttpResponseRedirect(redirect_url)
    else:
        problem_form = ProblemForm(responsibility=related_instance.id)

    context = {'problem_form': problem_form}
    
    return render(request, 'systemcockpit/problem_form.html', context)

Now I just have to let the logged-in user automatically fill in the form, then everything fits.

Ahh, I see - yes, you’re passing responsibility into the template through the context.

See the section in those docs where it’s talking about commit=False. The above line becomes something like:

    new_problem = problem_form.save(commit=False)

The variable, new_problem is now the instance of Problem created from the data in the form. You can now do anything you need to do with new_problem (alter fields, etc) before saving it.
You would then save new_problem. (e.g. new_problem.save().)

Wrong approach.

You use the url name and parameters in substantially the same way as in the template.
e.g. redirect_url = reverse('responsibility-details', args=[id])
or
replace this:

with:
return redirect('responsibility-details', id=id)
See the docs for redirect.

Ok, thank you very much. I will continue testing tomorrow. Here in Germany it is getting late, the night is calling :wink:

I really appreciate your support.