I have form with the name of CommentForm when the form is validated it has to return HttpResponse which is saying that the form is valid if does nothing
views.py
def comment(request,pk):
blog = BlogPost.objects.get(pk=pk)
comment = CommentForm()
if request.method == "POST":
comment = CommentForm(request.POST or None)
if comment.is_valid():
return HttpResponse('this is request method')
context = {
'blog':blog,
'comment':comment,
}
return render(request, 'blog/comment.html', context)
froms.py
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = '__all__'
models.py
class Comment(models.Model):
blog = models.ForeignKey('BlogPost', on_delete = models.CASCADE)
text = models.TextField()
template
{% extends 'base.html' %}
{% block content %}
{{blog.title}}
<form method="POST" action="">
{% csrf_token %}
{{comment.text}}
<input type="submit">
<form>
{% endblock %}
I used class meta in my forms.py I removed class meta and I save comments to model while instantiating it in view.py.
form.py
class CommentForm(forms.Form):
text = forms.CharField(widget=forms.Textarea())
view.py
def comment(request,pk):
blog = BlogPost.objects.get(id=pk)
form = CommentForm()
if request.method=='POST':
form = CommentForm(request.POST)
if form.is_valid():
comments = Comment(
text = form.cleaned_data['text'],
blog =blog
)
comments.save()
return redirect('/blog')
else:
context = {'blog':blog,
'form':form}
return render(request, 'blog/comment.html', context)
Related
This is my code:
django.models. my model.py file
from django.db import models
class Product(models.Model):title = models.CharField(max_length=150)
description = models.TextField(blank=True, null=True)
price = models.DecimalField(decimal_places=2, max_digits=100000)
summary = models.TextField(blank=True, null=False)
featured = models.BooleanField(default=False)
forms.py That's my full form.py file
from django import forms
from .models import Product
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = [
'title',
'description',
'price',
]
class RawProductForm(forms.ModelForm):
title = forms.CharField()
description = forms.CharField()
price = forms.DecimalField()
django.views my django.views file
from django.shortcuts import render
from .models import Product
from .forms import ProductForm, RawProductForm
def product_create_view(request):
my_form = RawProductForm()
if request.method == 'POST':
my_form = RawProductForm(request.POST)
if my_form.is_valid():
print(my_form.cleaned_data)
Product.objects.create(**my_form.cleaned_data)
else:
print(my_form.errors)
context = {'form': my_form}
return render(request, "products/product_create.html", context)
products_create.html this is my html file
{% extends 'base.html' %}
{% block content %}
<form action="." method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save" />
</form>
{% endblock %}
In his code I'm trying to make a form but when I run python manage.py runserver at http://127.0.0.1:8000/create/ I'm getting ValueError
This is a screenshot of my full error messagae
You need to specify your model class in your form :
class RawProductForm(forms.ModelForm):
class Meta:
model = Product
fields = ["price","description" ,"title"]
view :
def product_create_view(request):
my_form = RawProductForm()
if request.method == 'POST':
my_form = RawProductForm(request.POST)
if my_form.is_valid():
print(my_form.cleaned_data)
Product.objects.create(**my_form.cleaned_data)
else:
print(my_form.errors)
context = {'form': my_form}
return render(request, "products/product_create.html", context)
Im trying to let user create a post and select a category, but when it selects a category and I post it, it gives me the error: Exception Value: 'NoneType' object has no attribute 'add'.
If i go to my database, whatever I type, it is save except the category_id which is null.
This is my code
views.py:
#login_required(login_url='login')
def userposts_create_view(request):
form= UserPostForm(request.POST or None)
#print(request.POST)
if request.POST:# form.is_valid():
#data = form.cleaned_data
#print(data)
#categories = data.pop('categories', None)
categories = request.POST['categories']
content = request.POST['content']
title = request.POST['title']
public = False
if 'public' in request.POST and request.POST['public'] == 'on':
public = False
else:
public=True
#print(f"{categories}, {content}, {title}, {public}")
#user_post = UserPost.objects.create(**data, user=request.user)
user_post = UserPost.objects.create(content=content, title=title, public=public, user=request.user)#, categories=categories)
categories = Categories.objects.filter(name=Categories.name)
print(categories)
user_post.categories.get(categories)
return HttpResponseRedirect("/posted/")
context= {'form': form}
return render(request, 'posts/userposts-create-view.html', context)
#list view
#login_required(login_url='login')
def userposts_list_view(request):
allposts= UserPost.objects.all()
context= {'allposts': allposts,
}
return render(request, 'posts/userposts-list-view.html', context)
#detail view
#login_required(login_url='login')
def userposts_detail_view(request, id=None):
post= get_object_or_404(UserPost, id=id)
context= {'post': post,
}
return render(request, 'posts/userposts-detail-view.html', context)
I assume the error must be in the models but not sure...
Models.py
class Categories(models.Model):
name = models.CharField(max_length=100, verbose_name='Nombre')
def __str__(self):
return self.name
User= settings.AUTH_USER_MODEL
class UserPost(models.Model):
user= models.ForeignKey(User, null=False, editable=False, verbose_name='Usuario', on_delete=models.CASCADE)
title= models.CharField(max_length=500, null=False)
content= models.TextField(null=False)
categories = models.ForeignKey(Categories, null=True, blank=True, on_delete=models.CASCADE)
public = models.BooleanField(verbose_name='Privada?',default=True)
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Creado el ')
updated_at = models.DateTimeField(auto_now=True, verbose_name='Actualizado el ')
def __str__(self):
return self.title + ' | ' + str(self.user)
def save(self, *args, **kwargs):
super(UserPost, self).save(*args, **kwargs)
Forms.py
from django import forms
from .models import UserPost
class UserPostForm(forms.ModelForm):
class Meta:
model= UserPost
fields= ["title", "content","categories","public"]
create_view.html
{%extends 'layouts/layout.html'%}
<html>
<head>
<meta charset="UTF-8">
{% block title %}
Post
{% endblock title %}
</head>
<body>
<h1>Create Post</h1>
{% block content %}
<form enctype="multipart/form-data" method="POST" action="">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Post"/>
</form>
{% endblock content %}
urls.py
from django.urls import path
from . import views
from django.conf.urls import url, include
urlpatterns = [
path('articulos/', views.list, name = "list_articles"), #se utilizaria page para el menu
path('categoria/<int:category_id>', views.category, name="category"),
path('articulo/<int:article_id>', views.article, name="article"),
path('create/', views.userposts_create_view, name='create'),
path('posted/', views.userposts_list_view, name='list_view'),
path('posted/<int:id>', views.userposts_detail_view, name='one_posts'),
path('tus_ideas', views.index_page, name='tus_ideas')
]
please try this:
#login_required(login_url='login')
def userposts_create_view(request):
form= UserPostForm(request.POST or None)
if request.POST:
categories = request.POST['categories']
content = request.POST['content']
title = request.POST['title']
public = False
if 'public' in request.POST and request.POST['public'] == 'on':
public = False
else:
public=True
user_post = UserPost.objects.create(content=content, title=title, public=public, user=request.user,categories_id=categories)
return HttpResponseRedirect("/posted/")
context= {'form': form}
return render(request, 'posts/userposts-create-view.html', context)
user_post.categories.add(*categories) would work if categories is a ManyToMany field in your UserPost model whereas it it a ForeignKey in your code.
Change your categories fields to :
class UserPost(models.Model):
...
categories = models.ManyToManyField('Categories', null=True, blank=True)
I have a model as follow:
class Post(models.Model):
title = models.CharField(max_length=150)
author = models.ForeignKey(User, on_delete=models.CASCADE)
date_posted = models.DateTimeField(default=timezone.now)
imagefile = models.FileField(null=True, blank=True, upload_to='images', default='default.jpg')
There is a bug in the view file that, when I use class base view I can post the new post but whenever I use it as a function it does not save the form.
This one works(saves post in database):
class PostCreateView(LoginRequiredMixin, AjaxFormMixin, CreateView):
model = Post
template_name = "app/postform.html"
success_url = '/posts'
form_class = postform
But this one does not(does not save post in database):
#login_required
def PostCreateView(request):
if request.method == 'POST':
mform = postform(request.POST or None, request.FILES or None, instance=request.user)
if mform.is_valid():
mform.save() # when I print something here, Ill see something
messages.success(request, f'Yes!')
return redirect('posts')
else:
mform = postform()
return render(request, 'myapplication/postform.html', {'form': mform})
and in postform.html:
<form method="POST" action="" enctype="multipart/form-data">
<fieldset class="form-group">
{% csrf_token %}
<div class="content-section">
<!-- {{ form|crispy }} -->
</div>
</fieldset>
</form>
and form.py:
class postform(forms.ModelForm):
class Meta:
model = Post
fields = ("__all__")
exclude = ['date_posted']
I think the problem is that you form's model is post and you're assigning object of user as instance.
So try this way:
#login_required
def PostCreateView(request):
if request.method == 'POST':
mform = postform(request.POST or None, request.FILES or None)
if mform.is_valid():
post = mform.save(commit=False)
post.author = request.user
post.save()
messages.success(request, f'Yes!')
return redirect('posts')
else:
mform = postform()
return render(request, 'myapplication/postform.html', {'form': mform})
I'm trying to upload file in a specific folder and store its path in DB through forms(CBV), but it doesn't work!!
this is my code (forms, models, views, template).
I'm selecting the file through forms then I submit the form, but it doesn't submit.
#views.py
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
# fields = ['title', 'content']
success_url = reverse_lazy('blog/new_post.html')
template_name = 'blog/new_post.html'
form_class = PostCreateForm
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect(self.success_url)
else:
return render(request, self.template_name, {'form': form})
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
#model.py
class Post(models.Model):
title = models.CharField(max_length=1000)
content = models.TextField()
xml_file = models.FileField(null=True, upload_to='xml_files')
rate = models.FloatField(null=True, blank=True, default=None)
post_date = models.DateTimeField(default=timezone.now)
post_update = models.DateTimeField(auto_now=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
# return '/detail/{}'.format(self.pk)
return reverse('detail', args=[self.pk])
class Meta:
ordering = ('-post_date', )
#forms.py
class PostCreateForm(forms.ModelForm):
title = forms.CharField( max_length=1000)
content = forms.CharField(widget=forms.Textarea(
attrs={'rows': 15, 'placeholder': 'write here'}
), max_length=50000)
xml_file = forms.FileField(label='upload file')
class Meta:
model = Post
fields = ['title', 'content', 'xml_file', ]
#new_post.html
{% block content %}
{% load crispy_forms_tags %}
<div class="border p-4 mb-5">
<legend class="border-bottom pb-1 mb-3">new post</legend>
<form method="POST">
{% csrf_token %}
{{form|crispy}}
<input class="btn btn-secondary mt-4" type="submit" value="post">
</form>
</div>
{% endblock content %}
When you are uploading media like what you've got, it is necessary to add the following part to your <form>:
enctype=multipart/form-data
I want add comment to post on his page ("post detail" page).
I was find answer, but it create comment on other page. I want create comment on page of "post detail".
urls.py
url(r'^post/(?P<pk>\d+)/create/$', views.CommentCreate.as_view(), name='comment_create'),
models.py
class Comment(models.Model):
description = RichTextUploadingField()
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
comment_date = models.DateTimeField(auto_now_add=True, null=True)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
class Meta:
ordering = ["-comment_date"]
def __str__(self):
return "{}".format(self.description)
forms.py
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['description']
views.py
class PostDetailView(generic.DetailView):
model = Post
class CommentCreate(LoginRequiredMixin, CreateView):
model = Comment
fields = ['description']
def get_context_data(self, **kwargs):
context = super(CommentCreate, self).get_context_data(**kwargs)
context['post'] = get_object_or_404(Post, pk = self.kwargs['pk'])
return context
def form_valid(self, form):
form.instance.author = self.request.user
form.instance.post=get_object_or_404(Post, pk = self.kwargs['pk'])
return super(CommentCreate, self).form_valid(form)
def get_success_url(self):
return reverse('post-detail', kwargs={'pk': self.kwargs['pk'],})
comment_form.html
...
<form action="" method="post">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<button type="submit">Submit</button>
</form>
...
post_detail.html
...
{% for comment in post.comment_set.all %}
<p>{{ comment.author }} ({{ comment.comment_date }}) {{ comment.description|safe }}</p>
{% endfor %}
<hr>
{% if user.is_authenticated %}
<p>Add a new comment</p>
...
I think, "comment_form" need to redirect to "post_detail", not generate new page for comment form.
And сould you tell, which parameters has a RichTextField (CKE), how change width, height field only in comment?
If you want the comment form right in your detail page then all you have to do is to add the form and post function in your View,
class PostDetailView(DetailView):
model = Post
template_name = 'yourdetailpage.html'
def get_context_data(self, **kwargs):
context = super(PostDetailView, self).get_context_data(**kwargs)
context['commentform'] = CommentForm()
return context
def post(self, request, pk):
post = get_object_or_404(Post, pk=pk)
form = CommentForm(request.POST)
if form.is_valid():
obj = form.save(commit=False)
obj.post = post
obj.author = self.request.user
obj.save()
return redirect('detail', post.pk)
And now you can add your form in your html. And add a submit button to post comment.