简体   繁体   中英

How can I assign the logged in (authenticated) user to the form data they submit?

I am developing an employee feedback interface with Django. They shall be able to log in and submit a complaint. That complaint is supposed to be stored in the database with the user who submitted it as an attribute.

I have tried to somehow pass the user to the form so that the form saves the authenticated user's username, but I haven't been able to pass data from a view to a form. I have been able to integrate a ModelChoiceField() to the ModelForm, but that lets the authenticated user manipulate the username that the complaint is going to be associated with.

models.py:

from django.db import models
from django.contrib.auth.models import User


class Complaint(models.Model):
    complaint_text = models.CharField(max_length=1000, default='')
    switch_schedule_yes_or_no = models.BooleanField(default=True)
    user = models.ForeignKey(User, default=1, on_delete=models.CASCADE)

views.py:

from .forms import ComplaintForm
from django.contrib.auth.decorators import login_required
from django.shortcuts import render


@login_required()
def complaint_view(request):
    form = ComplaintForm(request.POST)
    if form.is_valid():
        form.save()
        form = ComplaintForm()

    context = {
        'form': form,
    }
    return render(request, 'complaint.html', context)

forms.py:

from django import forms
from .models import Complaint
from django.contrib.auth.models import User


class ComplaintForm(forms.ModelForm):
    complaint_text = forms.CharField(max_length=1000)
    switch_schedule_yes_or_no = forms.BooleanField()
    user = forms.ModelChoiceField(queryset=User.objects.all())

    class Meta:
        model = Complaint
        fields = ['complaint_text', 'switch_schedule_yes_or_no', 'user']

If it is possible to somehow design this is a way that allows the complaint to be associated with the authenticated user, that would be amazing! Be it by passing parameters from a view to a form or by using user-individual URLS. I have been trying to solve this for days now.

Cheers!

You can use request.user to access the authenticated user and associate with you Complaint object. You don't need the user field in the ComplaintForm form.

@login_required()
def complaint_view(request):
    form = ComplaintForm(request.POST)
    if form.is_valid():
        complaint = form.save(commit=False)  #don't commit to DB
        complaint.user = request.user  #access the user
        complaint.save()   # save and commit to DB
        form = ComplaintForm()

    context = {
        'form': form,
    }
    return render(request, 'complaint.html', context)

Try the following Class Based View Approach

In your form, you can ommit this line:

user = forms.ModelChoiceField(queryset=User.objects.all())

from django.views import generic

from my_app.forms import ComplaintForm

class ComplaintView(generic.CreateView):
    template_name = "complaint.html"
    form_class = ComplaintForm

    def form_valid(self, form):
        form.instance.user = self.request.user  # This is where what you want happens
        super().form_valid(form)

And to add the login required constraint, you can use the LoginRequiredMixin :

from django.contrib.auth.mixins import LoginRequiredMixin

class ComplaintView(LoginRequiredMixin, generic.CreateView):
    pass

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM