I am trying to add a httpresponseredirect to my class-based CreateView instead of a reverse-lazy, but I am getting errors. Here is my view:
class ApplicantCreate(CreateView):
model = Applicant
success_message = 'Your application was submitted successfully.'
form_class = forms.ApplicantForm
template_name = 'careers/add_applicant.html'
success_url = reverse_lazy('careers:thanks')
def form_valid(self, form):
context = self.get_context_data()
employer = context['employer']
education = context['education']
with transaction.atomic():
form.instance.created_by = self.request.user
self.object = form.save()
if employer.is_valid():
employer.instance = self.object
employer.save()
if education.is_valid():
education.instance = self.object
education.save()
return super(ApplicantCreate, self).form_valid(form)
def get_success_url(self):
return reverse_lazy('careers:thanks')
Thank you for any help.
Related
This question already has an answer here:
Django: How to provide context for a FormView?
(1 answer)
Closed 1 year ago.
I have a registration page, how can I pass the context to the header to display information in the header from the database
view
class RegisterFormView(FormView):
form_class = UserCreationForm
success_url = '/login/'
template_name = 'essense/registration.html'
def form_valid(self, form):
form.save()
return super(RegisterFormView, self).form_valid(form)
def form_invalid(self, form):
return super(RegisterFormView, self).form_invalid(form)
you can pass data using get_context_data
class RegisterFormView(FormView):
form_class = UserCreationForm
success_url = "/login/"
template_name = "essense/registration.html"
def get_context_data(self, **kwargs):
context = super(RegisterFormView, self).get_context_data(**kwargs)
# here you can pass any type of data
context["variable_name"] = "value"
return context
def form_valid(self, form):
form.save()
return super(RegisterFormView, self).form_valid(form)
def form_invalid(self, form):
return super(RegisterFormView, self).form_invalid(form)
I am trying to get my head around how to upload and post an image through my Django form. I have sussed out how to post content, but not Images.
At the moment, when I try to upload an image with my Post, the following error is returned:
null value in column "author_id" violates not-null constraint
Views.py
class CreatePostView(LoginRequiredMixin, CreateView):
model = Post
fields = ['content', 'image']
template_name = 'core/post_new.html'
success_url = '/'
#login_required
def post_image(request):
form=upl()
if request.method == 'POST':
form = upl(request.POST, request.FILES)
upl.save()
return render(request, 'core/post_new.html', {'form': form})
def form_valid(self, form):
form.instance.author_id = self.request.user
return super().form_valid(form)
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
data['tag_line'] = 'Create new post'
return data
Models.py
class Post(models.Model):
content = models.TextField(max_length=1000)
date_posted = models.DateTimeField(default=timezone.now)
image = models.ImageField(default='default.png', upload_to='core_media')
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.content[:5]
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.image.path)
UPDATED Views.py
class CreatePostView(LoginRequiredMixin, CreateView):
model = Post
fields = ['content', 'image']
template_name = 'core/post_new.html'
success_url = '/'
#login_required
def post_image(request):
form=upl()
if request.method == 'POST':
form = upl(request.POST, request.FILES)
upl.save()
return render(request, 'core/post_new.html', {'form': form})
def form_valid(self, form):
form.instance.author_id = self.request.user
return super().form_valid(form)
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
data['tag_line'] = 'Create new post'
return data
Any assistance/direction would be most appreciated. Thank you :)
The form_valid and get_context_data are here no members of your CreatePostView, but inner functions of the post_image function.
You should implement this as:
class CreatePostView(LoginRequiredMixin, CreateView):
model = Post
fields = ['content', 'image']
template_name = 'core/post_new.html'
success_url = '/'
# ↓ ↓ method of the CreatePostView
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
# ↓ ↓ method of the CreatePostView
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
data['tag_line'] = 'Create new post'
return data
I am trying to add inlineformset to the Django Blog project. I got post and I want to add multiple images to the post via Class Based Views. But when I am trying to get_context_data I receive this error:
get_context_data() missing 1 required positional argument: 'form'
Models.py:
class Post(models.Model):
title = models.CharField(max_length=100)
content = RichTextField(blank=True, null=True)
class PostImage(models.Model):
post = models.ForeignKey(Post, default=None, on_delete=models.CASCADE)
image = models.ImageField(upload_to='gallery/')
description = models.CharField(max_length=300, blank=True)
Forms.py
class CreatePostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title' , 'content' ]
PostImageFormSet = inlineformset_factory(Post, PostImage, fields=['image', 'description'], exclude=['post'] , max_num=30, extra=3)
Views.py
class PostCreateView(LoginRequiredMixin, CreateView):
form_class = CreatePostForm
template_name = 'blog/post_form.html'
def get_context_data(self, form):
context = super(PostCreateView. self).get_context_data(**kwargs)
if self.request.POST:
context['post_images'] = PostImageFormSet(self.request.POST)
else:
context['post_images'] = PostImageFormSet()
return context
def form_valid(self, form):
context = self.get_context_data(form=form)
formset = context['post_images']
form.instance.author = self.request.user
if formset.is_valid():
response = super().form_valid(form)
formset.instance = self.object
formset.save()
return response
else:
return super().form_invalid(form)
Any idea why I am receiving this kind of error? Thank you.
You should remove the form parameter. The form is never used in the get_context_data anyway:
class PostCreateView(LoginRequiredMixin, CreateView):
form_class = CreatePostForm
template_name = 'blog/post_form.html'
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
if self.request.POST:
context['post_images'] = PostImageFormSet(self.request.POST)
else:
context['post_images'] = PostImageFormSet()
return context
def form_valid(self, form):
context = self.get_context_data()
formset = context['post_images']
form.instance.author = self.request.user
if formset.is_valid():
response = super().form_valid(form)
formset.instance = self.object
formset.save()
return response
else:
return super().form_invalid(form)
I hope you are well.
I'm trying to create comment for user with one form field (content). I'd like to have the user field automatically filled in user value.
I. I started with this model but I got an error (1048, “Column 'user_id' cannot be null”):
models.py
class Comment(models.Model):
post = models.ForeignKey(Post,on_delete=models.CASCADE,related_name="comments")
user = models.ForeignKey(User,on_delete=models.CASCADE)
content = models.TextField(max_length=160)
publishing_date = models.DateField(auto_now_add=True)
def __str__(self):
return self.post.title
views.py
class PostDetail(generic.DetailView,FormMixin):
model = Post
context_object_name = 'post'
template_name = 'post_detail.html'
form_class = CreateCommentForm
def get_context_data(self, **kwargs):
context = super(PostDetail, self).get_context_data(**kwargs)
context['form'] = self.get_form()
return context
def form_valid(self, form):
if form.is_valid():
form.instance.post = self.object
form.save()
return super(PostDetail, self).form_valid(form)
else:
return super(PostDetail, self).form_invalid(form)
def post(self,*args,**kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_valid(form)
def get_success_url(self):
return reverse('post_detail',kwargs={"slug":self.object.slug})
forms.py
class CreateCommentForm(forms.ModelForm):
def __init__(self,*args,**kwargs):
super(CreateCommentForm, self).__init__(*args,**kwargs)
self.helper = FormHelper()
self.helper.form_method="post"
self.helper.layout = Layout(
Field("content",css_class="form-control",style="margin-bottom:10px",rows="1"),
)
self.helper.add_input(Submit('submit','Comment',css_class="btn btn-sm",style="background-color: #0d6ec5;border-color: #0d6ec5;"))
class Meta:
model = Comment
fields = [
'content'
]
II. It worked from my admin panel but not from my website (I got this error: (1048, “Column 'user_id' cannot be null”)).
So I've decided to change my models with:
class Comment(models.Model):
post = models.ForeignKey(Post,on_delete=models.CASCADE,related_name="comments")
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)
content = models.TextField(max_length=160)
publishing_date = models.DateField(auto_now_add=True)
def __str__(self):
return self.post.title
The thing is if a user post a comment, content is ok but there is no user related to the comment. Anyone has an idea?
You need to specify the .user attribute, probably to the logged in user:
from django.contrib.auth.mixins import LoginRequiredMixin
class PostDetail(LoginRequiredMixin, FormMixin, generic.DetailView):
model = Post
context_object_name = 'post'
template_name = 'post_detail.html'
form_class = CreateCommentForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form'] = self.get_form()
return context
def form_valid(self, form):
form.instance.post = self.object
form.instance.user = self.request.user
return super().form_valid(form)
def post(self,*args,**kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_valid(form)
def get_success_url(self):
return reverse('post_detail',kwargs={"slug":self.object.slug})
Note: You can limit views to a class-based view to authenticated users with the
LoginRequiredMixin mixin [Django-doc].
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
On my page, i need to display the post detail and a comment form for viewer to post comment. I created 2 generic views:
# views.py
class PostDetailView (DetailView):
model = Post
context_object_name = 'post'
template_name = 'post.html'
def get_context_data(self, **kwargs):
context = super(PostDetailView, self).get_context_data(**kwargs)
context['comment_form'] = CommentForm()
return context
class AddCommentView(FormView):
template_name = 'post.html'
form_class = CommentForm
success_url = '/'
def form_valid(self, form):
form.save()
return super(AddCommentView, self).form_valid(form)
def form_invalid(self, form):
return self.render_to_response(self.get_context_data(form=form))
detail = PostDetailView.as_view()
add_comment = AddCommentView.as_view()
# urls.py
....
url(r'^(?P<pk>\d+)/$', view='detail'),
url(r'^(?P<post_id>\d+)/add_comment/$', view='add_comment'),
....
Error would occur in the AddCommentView,since I haven't specified the post's id for the comment. How can I access the post_id in the AddCommentView?
self.kwargs['post_id'] or self.args[0] contains that value
Docs