Automatically filling in user into form in Django

Viewed 25

I am attempting to automatically assign a user to a questionnaire that they fill out.

Here is part of my views.py file:

@login_required
def questionnaireAnswerView(request):
    form = QuestionnaireForm(request.POST or None)

    if form.is_valid():
        form.save()
        return redirect("/accounts/profile/")

    context = {
        'form': form
    }
    return render(request, "questionnaire/createNewQuestionnaire.html", context)

This is my createNewQuestionnaire.html file:

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Create</title>
</head>
<body>

<form action="." method="POST">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Submit Questionnaire" />
</form>

</body>
</html>

Here is my form.py

class QuestionnaireForm(forms.ModelForm):
    class Meta:
        model = Questionnaire
        fields = [
            'name',
            'organisationType',
            'organisationIncome',
            'programArea',
            'appliedForFunding',
            'successfullyFundedBefore',
            'sourcesOfIncome',
            'planToGenerateIncome',
            'skillsToReachTargets',
            'processesToRecruit',
            'processesToUpskill',
            'confidentSpeakingAboutProject',
            'knowGoodCharity',
            'collectPastSuccessFunding',
            'collectPastFailedFunding',
            'areasOfAdditionalHelp'
        ]

And finally, this is part of my model.py. I have not shown the types of choices here.

class Questionnaire(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, unique=True)
    name = models.CharField(max_length=254, blank=False, null=False)
    organisationType = models.CharField(max_length=2, choices=typeOfCharity, blank=False, null=False)
    organisationIncome = models.CharField(max_length=1, choices=incomeLevels, blank=False, null=False)
    
    ...

I think I need to make changes to my veiws.py file. In particular, I believe I need to somehow access the form that is returned from the request.POST and then set the currently logged in user as the user required.

I have tried passing in the user through to the form itself and filling in the user field but this allows the interacting user to change who the questionnaire is assigned to.

1 Answers

You set the .user attribute of the .instance wrapped in the form:

@login_required
def questionnaireAnswerView(request):
    if request.method == 'POST':
        form = QuestionnaireForm(request.POST)
        if form.is_valid():
            form.instance.user = request.user
            form.save()
            return redirect('/accounts/profile/')
    else:
        form = QuestionnaireForm(request.POST)
    context = {
        'form': form
    }
    return render(request, 'questionnaire/createNewQuestionnaire.html', context)

Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.


Note: Usually it is better to work with a OneToOneField [Django-doc] instead of a ForeignKey that has unique=True. A OneToOneField is a ForeignKey with unique=True and some small modifications: for example it uses by default the name of the model in lowercase as related_name=… [Django-doc] and makes accessing the relation in reverse more convenient since that does not require a manager in between.

Related