Reputation: 1
When I try to save a post, the post is saved, but current user is not registered and the post is duplicated with a blank entry and the current user is not stored.
For adding the post I use not the admin app but a personal template and form.
This is my view code:
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from .forms import NewAdminPostForm
from .models import Post, Category
# Create your views here.
def home(request):
posts = Post.objects.all()
categories = Category.objects.all()
posts_last = Post.objects.order_by('-created_at')[0:3]
return render(request, 'front/blog-list.html', {'posts': posts,
'categories': categories, 'posts_last': posts_last})
@login_required
def newadminpost(request):
if request.method == 'POST':
form = NewAdminPostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
Post.objects.create(
message=form.cleaned_data.get('message'),
category_id=post.category_id,
created_by=request.user
)
@post.save()
return redirect('listadminpost')
else:
form = NewAdminPostForm()
return render(request, 'back/new-post-blog.html', {'form': form})
@login_required
def listadminpost(request):
posts = Post.objects.all()
return render(request, 'back/list-post-blog.html', {'posts': posts})
Form of my Blog:
from django import forms
from .models import Post, Category
class NewAdminPostForm(forms.ModelForm):
title = forms.CharField(label="Titre de l'article", max_length=255,)
message = forms.CharField(widget=forms.Textarea(),
max_length=4000,
help_text="Contenu de l'article")
pre_message = forms.CharField(label="Message de prévisu",
widget=forms.Textarea(),
max_length=4000,
help_text="Contenu de l'article")
class Meta:
model = Post
fields = ['title','meta_desc','message','pre_message','category']
Model of my Blog:
from django.db import models
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField(max_length=255, unique=True)
description = models.TextField(max_length=1000)
def __str__(self):
return self.name
def get_categories_count(self):
return Category.objects.filter(post__category=self).count()
class Post(models.Model):
title = models.CharField(max_length=255)
meta_desc = models.TextField(max_length=320, null=True)
pre_message = models.TextField(max_length=4000, null=True)
message = models.TextField(max_length=4000)
category = models.ForeignKey(Category, on_delete='cascade')
created_at = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey(User, on_delete=models.CASCADE,
blank=True, null=True)
def __str__(self):
return self.title
Upvotes: 0
Views: 84
Reputation: 9308
https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.create
your code:
post.save()...Post.objects.create(
from the link above:
A convenience method for creating an object and saving it all in one step. Thus:
p = Person.objects.create(first_name="Bruce", last_name="Springsteen")
and:
p = Person(first_name="Bruce", last_name="Springsteen")
p.save(force_insert=True)
are equivalent.
So what you do in your code:
post
object created from form
Post
instance by calling create
methodchoose any of them, just one, and this will avoid duplicates.
Upvotes: 2
Reputation: 15796
Instead of doing this:
@login_required
def newadminpost(request):
if request.method == 'POST':
form = NewAdminPostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
Post.objects.create(
message=form.cleaned_data.get('message'),
category_id=post.category_id,
created_by=request.user
)
@post.save()
return redirect('listadminpost')
else:
form = NewAdminPostForm()
return render(request, 'back/new-post-blog.html', {'form': form})
You could do this: cleaner, easier to read, more up-to-date, and easier to maintain:
class AdminCreateView(LoginRequiredMixin, generic.CreateView):
model = Request
form_class = RequestForm
def form_valid(self, form):
result = super(AdminCreateView, self).form_valid(form)
title = form.cleaned_data.get('title')
meta_desc = form.cleaned_data.get('meta_desc')
message = form.cleaned_data.get('message')
# and so on. if there's something you refuse (ex title empty) do this:
if not title:
form.add_error('title', _("Precise the title"))
return self.form_invalid(form)
Post.objects.create(message=message,
meta_desc=meta_desc,
title=title,) # and so on
return result
Upvotes: 0