Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set ForeignKey in CreateView?

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.

like image 507
Vlad T. Avatar asked Apr 30 '12 11:04

Vlad T.


3 Answers

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)
like image 70
Vlad T. Avatar answered Oct 09 '22 15:10

Vlad T.


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)
like image 41
Carlos Mermingas Avatar answered Oct 09 '22 16:10

Carlos Mermingas


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
        }
like image 27
jantoniomartin Avatar answered Oct 09 '22 17:10

jantoniomartin