In my django project, I'm trying create a 'submit post' page using CreateView. It works, but with a dropdown menu for the author of the post. I would like to have the author automatically added to the post.
According to the (documentation)[https://docs.djangoproject.com/en/4.1/topics/class-based-views/generic-editing/], I should use a form_valid method to add the author to the form. This does not work, even though it's copied directly from the documentation.
I've tried adding 'author'
to the fields in the PostCreate class, and that only adds the author dropdown box to the form.
Views.py:
class PostCreate(LoginRequiredMixin, CreateView):
model = Post
fields = ['image', 'description']
success_url = '/'
template_name: 'post_form.html'
def form_valid(self, form):
self.author = self.request.user
return super().form_valid(form)
changing to self.author = self.request.user.pk
does not work, either.
Models.py:
class Post(models.Model):
image = models.ImageField()
description = models.TextField(null=True )
author = models.ForeignKey(User, on_delete=models.CASCADE)
when looking at the debug error, I can see the author param is not passed, resulting in a NOT NULL constraint failed
.
It seems to be the problem is with this line:
def form_valid(self, form):
self.author = self.request.user ## The problem should be here
return super().form_valid(form)
I've changed this line to the following, with no success:
form.instance.author = self.request.user
form.instance.user = self.request.user
self.author = self.request.user
self.author = self.author.user.pk
In all of these changes, the traceback always passes None
to the params. This leads me to believe there is something wrong on another line.
Here is the urls.py:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from posts.views import PostList, PostCreate, PostDetail, Profile
from django.urls import reverse, re_path
urlpatterns = [
path('admin/', admin.site.urls),
path("accounts/", include("accounts.urls")),
path('accounts/', include('django.contrib.auth.urls')),
path('', PostList.as_view(), name='list'),
path('new/', PostCreate.as_view(), name='new'),
path('posts/<pk>/', PostDetail.as_view(), name='detail'),
path('<str:username>/', Profile.as_view(), name='user_profile'),
] static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
CodePudding user response:
Write form.instance.author=self.request.user
as form
contains all the instances after validation of form, so:
class PostCreate(LoginRequiredMixin, CreateView): model = Post fields = ['image', 'description'] success_url = '/' template_name='post_form.html' def form_valid(self, form): form.instance.author = self.request.user return super().form_valid(form)
Note
: class based views require their name to be written as model name as prefix and actual view name as the suffix, so you may it toPostCreateView
from.PostCreate
Edit:
I see a big mistake it should be template_name='post_form.html
, you have used :
instead of =
.