I have a model:
class Article(models.Model):
text = models.CharField()
author = models.ForeignKey(User)
How do I write class-based view that creates a new model instance and sets author foreign key to request.user?
Update:
Solution moved to separate answer below.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
I solved this by overriding form_valid method. Here is verbose style to clarify things:
class CreateArticle(CreateView):
model = Article
def form_valid(self, form):
article = form.save(commit=False)
article.author = self.request.user
#article.save() # This is redundant, see comments.
return super(CreateArticle, self).form_valid(form)
Yet we can make it short (thanks dowjones123), this case is mentioned in docs.:
class CreateArticle(CreateView):
model = Article
def form_valid(self, form):
form.instance.author = self.request.user
return super(CreateArticle, self).form_valid(form)
Method 2
I just stumbled into this problem and this thread led me in the right direction (thank you!). Based on this Django documentation page, we can avoid calling the form’s save() method at all:
class CreateArticle(LoginRequiredMixin, CreateView):
model = Article
def form_valid(self, form):
form.instance.author = self.request.user
return super(CreateArticle, self).form_valid(form)
Method 3
Berislav’s code in views.py doesn’t work for me. The form is rendered as expected, with the user value in a hidden input, but the form is not saved (I don’t know why). I have tried a slightly different approach, that works for me:
views.py
from django.views.generic import *
from myapp.forms import ArticleForm
from myapp.models import Article
class NewArticleView(CreateView):
model = Article
form_class = ArticleForm
def get_initial(self):
return {
"user": self.request.user
}
Method 4
You should set up a CreateView using a ModelForm for that model. In the form definition, you set the ForeignKey to have the HiddenInput widget, and then use the get_form method on the view to set the value of your user:
forms.py:
from django import forms
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
widgets = {"user": forms.HiddenInput()}
views.py:
from django.views.generic import *
from myapp.forms import ArticleForm
from myapp.models import Article
class NewArticleView(CreateView):
model = Article
form_class = ArticleForm
def get_form(self, form_class):
initials = {
"user": self.request.user
}
form = form_class(initial=initials)
return form
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0