Django creating update post function - django

I want to create a post update/edit function but I have a problem. When I click "Update" button there is no error but there is no change. I think reason of that a mistake that I made in models.py but I can not figure it out. And here is my code
models.py
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=200)
.
.
.
def get_update_url(self):
return reverse('post:post_update', kwargs={'slug': self.slug})
views.py
def post_update(request, slug):
if not request.user.is_authenticated():
return Http404()
post = get_object_or_404(Post, slug=slug)
form = PostForm(request.POST or None, request.FILES or None, instance=post)
if form.is_valid():
form.save()
messages.success(request, "Updated")
return HttpResponseRedirect(get_absolute_url())
context = {
'form': form
}
return render(request, "blog/post_update.html", context)
post_update.html
{% extends 'blog/base.html' %}
{% load crispy_forms_tags %}
{% block body %}
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1>Form</h1>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
{{ form.media }}
<input class="btn btn-primary" type="submit" value="Create post">
</form>
</div>
</div>
</div>
{% endblock %}
post_detail.html
//update link
<p >update</p>
urls.py
url(r'^(?P<slug>[\w-]+)/update/$', post_update, name="update"),
forms.py
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'text',)
Where is my mistake? What can I do?

Related

multiple forms in one step, Django Wizard form

I am trying to create 2 Model Forms in on Step, one of them is Modelformset, does someone did this before, it will be very helpful.
I am using Django 2 in my project.
Thank you.
class Post(models.Model):
main_image = models.ImageField('main_image', upload_to='main_images/', blank=True, null=True)
def __str__(self):
return str(self.pk)
class PostImages(models.Model):
image = models.ImageField('Foto', upload_to='post_images/', blank=True, null=True)
post = models.ForeignKey(Post,related_name='myposts',on_delete=models.CASCADE, null=True)
def __str__(self):
return str(self.pk)
my Forms.py
Here I am Trying to create two forms, first one is main_image and the other is formsetfield in one step. that works but i can not get the instance of my formset so i can not save it.
class step3Form(forms.ModelForm):
main_image = forms.FileField(widget=forms.FileInput(attrs={'class': 'custom-control'}), required=True, label=_('Hauptbild:'))
formsetfield = modelformset_factory(PostImages, ImageForm, can_delete=True)
class Meta:
model = Post
fields = ('main_image',)
def __init__(self, *args, **kwargs):
super(step3Form, self).__init__(*args, **kwargs)
views.py
what schuld I do here to get the instance of my Formset? in order to save it!
class PostCreateView(LoginRequiredMixin, SessionWizardView):
instance = None
form_list = [PostForm, PostFormSecondStep, step3Form, step4Form]
file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'media'))
def get_template_names(self):
return [TEMPLATES[self.steps.current]]
def get_form_instance(self, step):
if self.instance is None:
self.instance = Post()
return self.instance
def done(self, form_list, form_dict, **kwargs):
form_data_dict = self.get_all_cleaned_data()
result = {}
self.instance.author = self.request.user.profile
form_list[2].save()
self.instance.save()
form_data = [form.cleaned_data for form in form_list]
return redirect('post_app:post_create_page')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
html
<form method="post" id="msform" enctype="multipart/form-data">
{% csrf_token %}
{{ wizard.management_form }}
{% if wizard.form.forms %}
{% for form in wizard.form.forms %}
{{ form }}
{% endfor %}
{% else %}
{% if wizard.form.non_field_errors %}
<ul>
{% for error in wizard.form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
{{ wizard.form.main_image.label_tag }}
{{ wizard.form.main_image }}
{{ wizard.form.main_image.errors }}
{{ wizard.form.formsetfield.errors }}
<div id="formset" data-formset-prefix="{{ wizard.form.formsetfield.prefix }}">
{{ wizard.form.formsetfield.management_form }}
<div data-formset-body>
{% for form in wizard.form.formsetfield %}
{{ form.non_field_errors }}
{{ form.errors }}
<div data-formset-form>
{{ form }}
<span class="p-2"><a class="cursor-pointer" data-formset-delete-button><i class="far fa-trash-alt"></i></a></span>
</div>
{% endfor %}
</div>
<input type="button" class="btn btn-outline-dark" value="Hinzufügen" data-formset-add>
</div>
{% endif %}
<button type="submit" id="submit_btn" class="action-button" name="button">Weiter</button>
{% if wizard.steps.prev %}
<button name="wizard_goto_step" class="action-button" type="submit" value="{{ wizard.steps.first }}">Erster Schritt</button>
<button name="wizard_goto_step" id="back_btn" class="action-button" type="submit" value="{{ wizard.steps.prev }}">Zurück</button>
{% endif %}
</form>
try this in function based:
Forms.py
class step3Form(forms.ModelForm):
class Meta:
model = Post
fields = ('main_image',)
view.py
from django.forms import modelformset_factory
def create(request):
formset = modelformset_factory(
Post,
form=step3Form,
fields=('main_image'),
extra=1,
can_delete=True
)
if request.method == 'POST':
form = formset(request.POST, prefix='post')
if form.is_valid()
post = form.save(commit=False)
for row in post:
row.userID = request.user
row.save()
form.save()
context['form']=formset(queryset=Post.objects.none(), prefix='post')
return render(request, 'post/form.html',context=context)

Django blog post_update function not working as intended

I am following a youtube channel to create a blog. I am stuck at post_update function. when i try to update the post the comment is getting updated, which should not happen in this scenario. where am I going wrong?
def post_update(request, id):
title = 'Update'
post = get_object_or_404(Post, id=id)
form = PostForm(
request.POST or None,
request.FILES or None,
instance=post)
author = get_author(request.user)
if request.method == "POST":
if form.is_valid():
form.instance.author = author
form.save()
return redirect(reverse("post-detail", kwargs={
'id': form.instance.id
}))
context = {
'title': title,
'form': form
}
return render(request, "post_create.html", context)
views.py
from django.db.models import Count, Q
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.shortcuts import render, get_object_or_404, redirect, reverse
from .forms import CommentForm, PostForm
from .models import Post, Author
from marketing.models import Signup
def get_author(user):
qs= Author.objects.filter(user=user)
if qs.exists():
return qs[0]
return None
def search(request):
queryset = Post.objects.all()
query = request.GET.get('q')
if query:
queryset = queryset.filter(
Q(title__icontains = query) |
Q(overview__icontains = query)
).distinct()
context = {
'queryset' : queryset
}
return render(request, 'search_results.html', context)
def get_category_count():
queryset = Post \
.objects \
.values('categories__title') \
.annotate(Count('categories__title'))
return queryset
def index(request):
featured = Post.objects.filter(featured=True)
latest = Post.objects.order_by('-timestamp')[:3]
if request.method == "POST":
email = request.POST['email']
new_signup = Signup()
new_signup.email = email
new_signup.save()
context = {
'object_list' : featured ,
'latest' :latest
}
return render(request, 'index.html', context)
def blog(request):
category_count = get_category_count()
#print(category_count)
most_recent = Post.objects.order_by('-timestamp')[:3]
post_list = Post.objects.all()
paginator = Paginator(post_list, 4)
page_request_var ='page'
page = request.GET.get(page_request_var)
try:
paginated_queryset = paginator.page(page)
except PageNotAnInteger:
paginated_queryset = paginator.page(1)
except EmptyPage:
paginated_queryset = paginator.page(paginator.num_pages)
context = {
'queryset' : paginated_queryset,
'most_recent' : most_recent,
'page_request_var': page_request_var,
'category_count': category_count
}
return render(request, 'blog.html', context)
def post(request, id):
most_recent = Post.objects.order_by('-timestamp')[:3]
category_count = get_category_count()
post = get_object_or_404(Post, id=id)
form = CommentForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
form.instance.user= request.user
form.instance.post = post
form.save()
return redirect(reverse("post-detail", kwargs={
'id' : post.id
}))
context ={
'form' : form,
'post' : post,
'most_recent' : most_recent,
'category_count': category_count
}
return render(request, 'post.html', context)
def post_create(request):
title = 'Create'
form = PostForm(request.POST or None, request.FILES or None)
author = get_author(request.user)
if request.method == "POST":
if form.is_valid():
form.instance.author= author
form.save()
return redirect(reverse("post-detail", kwargs={
'id' : form.instance.id
}))
context = {
'title': title,
'form' : form
}
return render(request, "post_create.html", context)
def post_update(request, id):
title = 'Update'
post = get_object_or_404(Post, id=id)
form = PostForm(
request.POST or None,
request.FILES or None,
instance=post)
author = get_author(request.user)
if request.method == "POST":
if form.is_valid():
form.instance.author = author
form.save()
return redirect(reverse("post-detail", kwargs={
'id': form.instance.id
}))
context = {
'title': title,
'form': form
}
return render(request, "post_create.html", context)
def post_delete(request, id):
post = get_object_or_404(Post, id=id)
post.delete()
return redirect(reverse("post-list"))
Whatever is present in content is getting updated as comment which should not happen I am not able to understand the flow. And also <P> tag is visible which I have not used in html.
post_create.html
{% extends 'base.html ' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="col-4 offset-4 mb-5 mt-5">
<h3>{{ title }} an Article</h3>
{{ form.media }}
<form method="POST" action="." enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
<button class="btn btn-primary" type="submit">Submit</button>
</form>
</div>
{% endblock content %}
model.py
from django.db import models
from django.contrib.auth import get_user_model
from django.urls import reverse
from tinymce import HTMLField
User = get_user_model()
# class PostView(models.Model):
# user = models.ForeignKey(User, on_delete=models.CASCADE)
# post = models.ForeignKey('Post', on_delete=models.CASCADE)
# def __str__(self):
# return self.user.username
class Author(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
profile_picture = models.ImageField()
def __str__(self):
return self.user.username
class Category(models.Model):
title = models.CharField(max_length = 20)
def __str__(self):
return self.title
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=100)
overview = models.TextField()
timestamp = models.DateTimeField(auto_now_add=True)
content = HTMLField()
comment_count = models.IntegerField(default =0)
view_count = models.IntegerField(default =0)
author = models.ForeignKey(Author, on_delete = models.CASCADE)
thumbnail = models.ImageField()
categories = models.ManyToManyField(Category)
featured = models.BooleanField()
previous_post = models.ForeignKey('self', related_name = 'previous', on_delete = models.SET_NULL, blank=True, null = True)
next_post = models.ForeignKey('self', related_name = 'next', on_delete = models.SET_NULL, blank=True, null = True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={
'id': self.id
})
def get_update_url(self):
return reverse('post-update', kwargs={
'id': self.id
})
def get_delete_url(self):
return reverse('post-delete', kwargs={
'id': self.id
})
#property
def get_comments(self):
return self.comments.all().order_by('-timestamp')
class Comment(models.Model):
user = models.ForeignKey(User, on_delete = models.CASCADE)
timestamp = models.DateTimeField(auto_now_add=True)
content = models.TextField()
#profile_picture = models.ImageField()
post = models.ForeignKey(Post, related_name='comments', on_delete = models.CASCADE)
def __str__(self):
return self.user.username
post.html
{% extends 'base.html ' %}
{% load static %}
{% block content %}
<style>
.post-body img {
width: 100%;
}
</style>
<div class="container">
<div class="row">
<!-- Latest Posts -->
<main class="post blog-post col-lg-8">
<div class="container">
<div class="post-single">
<div class="post-thumbnail"><img src="{{ post.thumbnail.url }}" alt="..." class="img-fluid"></div>
<div class="post-details">
<div class="post-meta d-flex justify-content-between">
<div class="category">
{% for cat in post.categories.all %}
{{ cat }}
{% endfor %}
</div>
<div>
Update
Delete
</div>
</div>
<h1>{{ post.title }}<i class="fa fa-bookmark-o"></i></h1>
<div class="post-footer d-flex align-items-center flex-column flex-sm-row"><a href="#" class="author d-flex align-items-center flex-wrap">
<div class="avatar"><img src="{{ post.author.profile_picture.url }}" alt="..." class="img-fluid"></div>
<div class="title"><span>{{ post.author.user.username }}</span></div></a>
<div class="d-flex align-items-center flex-wrap">
<div class="date"><i class="icon-clock"></i> {{ post.timestamp|timesince }} ago</div>
<div class="views"><i class="icon-eye"></i> {{ post.view_count }}</div>
<div class="comments meta-last"><i class="icon-comment"></i>{{ post.comment_count }}</div>
</div>
</div>
<div class="post-body">
{{ post.content|safe }}
</div>
<div class="posts-nav d-flex justify-content-between align-items-stretch flex-column flex-md-row">
{% if post.previous_post %}
<a href="{{ post.previous_post.get_absolute_url }}" class="prev-post text-left d-flex align-items-center">
<div class="icon prev"><i class="fa fa-angle-left"></i></div>
<div class="text"><strong class="text-primary">Previous Post </strong>
<h6>{{ post.previous.title }}</h6>
</div>
</a>
{% endif %}
{% if post.next_post %}
<a href="{{ post.next_post.get_absolute_url }}" class="next-post text-right d-flex align-items-center justify-content-end">
<div class="text"><strong class="text-primary">Next Post </strong>
<h6>{{ post.next.title }}</h6>
</div>
<div class="icon next"><i class="fa fa-angle-right"> </i></div>
</a>
{% endif %}
</div>
<div class="post-comments">
<header>
<h3 class="h6">Post Comments<span class="no-of-comments">{{ post.comments.count }}</span></h3>
</header>
{% for comment in post.get_comments %}
<div class="comment">
<div class="comment-header d-flex justify-content-between">
<div class="user d-flex align-items-center">
<div class="image">
{% if comment.user.author %}
<img src="{{ comment.user.author.profile_picture.url }}" alt="NA" class="img-fluid rounded-circle">
{% else %}
<img src="{% static 'img/user.svg' %}" alt="..." class="img-fluid rounded-circle">
{% endif %}
</div>
<div class="title"><strong>{{ comment.user.username }}</strong><span class="date">{{ comment.timestamp|timesince }} ago</span></div>
</div>
</div>
<div class="comment-body">
<p>{{ comment.content }}</p>
</div>
</div>
{% endfor %}
</div>
{% if request_user.is_authenticated %}
<div class="add-comment">
<header>
<h3 class="h6">Leave a reply</h3>
</header>
<form method ="POST" action="." class="commenting-form">
{% csrf_token %}
<div class="row">
<div class="form-group col-md-12">
{{ form }}
</div>
<div class="form-group col-md-12">
<button type="submit" class="btn btn-secondary">Submit Comment</button>
</div>
</div>
</form>
</div>
{% endif %}
</div>
</div>
</div>
</main>
{% include 'sidebar.html' with most_recent=most_recent category_count=category_count %}
</div>
</div>
{% endblock %}

Django: form not displaying in browser

The form doesn't display in the browser. The navbar and submit button show up but no form in between. The problem must be straightforward but I haven't been able to find the issue. Thank you for your help.
views.py
def ProductCreateView(request):
if request.method == 'POST':
form = ProductForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('set_app/product_list.html'))
else:
product_form = ProductForm()
return render(request, 'set_app/product_form.html', {'product_form':product_form})
forms.py
class ProductForm(forms.Form):
class Meta():
model = models.Product
fields = ('code', 'barcode', 'name', 'description', 'brand', 'status')
product_form.html
{% extends "set_app/basic_app_base.html" %}
{% block body_block %}
<h1>
{% if not form.instance.pk %}
Create Product
{% else %}
Update Product
{% endif %}
</h1>
<form method="post">
{% csrf_token %}
{{ product_form.as_p }}
<input type="submit" class="btn btn-primary" value="Submit">
</form>
{% endblock %}
Found the issue:
in forms.py
instead of
class ProductForm(forms.Form):
it should be
class ProductForm(forms.ModelForm):

PasswordChangeForm with Abstractuser not responsive on submit

I have a custom user model
class User(AbstractUser):
company = models.CharField(max_length=30, blank=True)
When I try to change my password using the ChangePasswordForm, upon submit, nothing happens.
#login_required
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(data=request.POST, user=request.user)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
return redirect('/account/profile')
else:
form = PasswordChangeForm(request.user)
args = {'form': form}
return render(request, 'accounts/change_password.html', args)
change_password.html
{% extends 'base.html' %}
{% block head %}
{% endblock %}
{% load crispy_forms_tags %}
{% crispy form form.helper %}
{% block body %}
<div class="container-fluid">
<div class="card">
<div class="card-body">
<h3>Change password</h3><br>
<form method="post">
{% csrf_token %}
{% crispy form %}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</div>
{%endblock%}
This was working before with a regular usermodel
hope someone can help.

nothing happens when submitting django form

I have a problem with django forms, when submitting a form nothing seems to happen, even the server didn't get any response except GET request to view the form template.
here is my code for the forms.py :
from django.forms import ModelForm
from .models import Post
class PostForm(ModelForm):
class Meta:
model = Post
fields = [
"title",
"content",
"category"
]
and here is my post_form.html :
{% extends 'base.html' %}
{% block content %}
<h1>form</h1>
<form method="POST" action=".">
{% csrf_token %}
{{ form.as_p }}
</form>
<button type="submit">Create Post</button>
{% endblock content %}
and here is my handling for the form in views.py :
def post_create(request):
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.save()
return redirect("posts:detail", pk=post.pk)
else :
form = PostForm()
context = {
"form":form,
}
return render(request,"post_form.html", context)
forms.py
from django.forms import ModelForm
from .models import Post
class PostForm(ModelForm):
class Meta:
model = Post
fields = ["title", "content", "category"]
views.py
def post_create(request):
form = PostForm()
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
post = form.save()
return redirect("posts:detail", pk=post.pk)
return render(request,"post-form.html", {"form": form})
post-form.html
{% extends 'base.html' %}
{% block content %}
<h1>form</h1>
{% for error in form.non_field_errors %}
<article class="message is-danger alert-message">
<div class="message-body">
<p>{{ error|escape }}</p>
</div>
</article>
{% endfor %}
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Create Post">
</form>
{% endblock content %}
in your views:
if form.is_valid():
form.commit = False
form.save()
or
if form.is_valid():
form.save(commit=false)
I suggest the latter
Don't Forget Place Your Submit Button In Form Tag !