How do I set user field in form to the currently logged in user?
Assumptions
We don't want to set
null=True
becaues we don't want to allownull
users at the model and/or database levelWe don't want to set
blank=True
to mess with the readability of model because the user actually will not be blank
@nbm.ten solution is a good one. It has an advantages over other 'solutions'to this problem that utilized model to set the user (like this one) in nbm.ten's doesn't undermine the assumptions above. We don't want to mess with the model to fix a problem in view!
But here I add two other solutions based on django documentation (Models and request.user):
Two other solutions
1. Using the generic CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.edit import CreateView
from myapp.models import Candidate
class CandidateCreate(LoginRequiredMixin, CreateView):
model = Candidate
exclude = ['user']
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
2. Using class-based views
class CandidateForm(ModelForm):
class Meta:
model = Candidate
exclude = [ 'user',]
class CandidateAddView(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs):
form = CandidateForm()
context = {'form':form}
return render(request, 'myapp/addcandidateview.html', context)
def post(self, request, *args, **kwargs):
form = CandidateForm(request.POST)
form.instance.user = request.user
if form.is_valid():
form.save()
return redirect(reverse('myapp:index'))
NOTES
Note that
LoginRequiredMixin
prevents users who aren’t logged in from accessing the form. If we omit that, we'll need to handle unauthorized users inform_valid()
orpost()
.Also
exclude = ['user']
prevents the user field to be shown on the form.We used
form.instance.user
to set the user notform.data
orform.cleaned_data
they don't work
Remove user field from rendered form (using
exclude
orfields
, https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#selecting-the-fields-to-use )class CandidateForm(forms.ModelForm): class Meta: model = Candidate exclude = ["user"]
Find user profile and set user field in the create view.
class CandidateCreateView(CreateView): ... def form_valid(self, form): candidate = form.save(commit=False) candidate.user = UserProfile.objects.get(user=self.request.user) # use your own profile here candidate.save() return HttpResponseRedirect(self.get_success_url())