Exception Type:NoReverseMatch this error is occurring during clicking the cancel button on web site. this cancel button is for canceling the delete process of post.
searched everywhere but unable to understand the error. also made some changes some in code but didn't work.
path("by/<username>/<int:pk>/", views.post_detail,name='post_detail'),
views.py
def post_detail(request,pk):
post = Post.object.get(pk=pk)
comments = Comment.objects.filter(post=post)
context = {
'post':post,
'comments':comments,
}
return render(request,'posts/post_detail.html',context)
class DeletePost(LoginRequiredMixin, SelectRelatedMixin, generic.DeleteView):
model = models.Post
select_related = ("user", "group")
success_url = reverse_lazy("posts:all")
def get_queryset(self):
queryset = super().get_queryset()
return queryset.filter(user_id=self.request.user.id)
def delete(self, *args, **kwargs):
messages.success(self.request, "Post Deleted")
return super().delete(*args, **kwargs)
moels.py
class Post(models.Model):
title = models.CharField(max_length=255,default='')
user = models.ForeignKey(User, related_name="posts",on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now=True)
message = models.TextField()
message_html = models.TextField(editable=False)
group = models.ForeignKey(Group, related_name="posts",null=True, blank=True,on_delete=models.CASCADE)
def __str__(self):
return self.message
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse(
"posts:post_detail",
kwargs={
"username": self.user.username,
"pk": self.pk
}
)
class Meta:
ordering = ["-created_at"]
unique_together = ["user", "message"]
post_confirm_delete.html and _post.html
{% extends "posts/post_base.html" %}
{% block post_content %}
<h3>Are you sure you want to delete this post?</h3>
<div class="posts">
{% include "posts/_post.html" with post=object hide_delete=True %}
</div>
<form method="POST">
{% csrf_token %}
<input type="submit" value="Confirm Delete" class="btn btn-danger btn-large">
Cancel
{% endblock %}
{% if user.is_authenticated and post.user == user and not hide_delete %}
<a href="{% url 'posts:delete' username=post.username pk=post.pk %}" title="delete" class="btn btn-simple">
<span class="fa fa-remove text-danger" aria-hidden="true"></span>
<span class="text-danger icon-label">Delete</span>
</a>
expected to cancel the process and go back. and also delete the post on delete command.
In Html Page
change this url
by/username=request.username/pk=post.pk
Related
I am learning Python and Django, and I am trying to create a recipe with a form. The problem is I have two models, Recipe and RecipeIngredient and I don't know how to add recipe ingredients to the form since it requires the primary key of the recipe and from what I understand, the key is not created until after the form is saved? So how can I create a recipe with both the Recipe and RecipeIngredient when Recipe is not yet initialized?
Models.py:
class Recipe(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
image = models.ImageField(upload_to='image/', blank=True, null=True)
name = models.CharField(max_length=220) # Lasanga
description = models.TextField(blank=True, null=True)
notes = models.TextField(blank=True, null=True)
cookTime = models.CharField(max_length=50, blank=True, null=True)
timeStamp = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)
#property
def title(self):
return self.name
def get_absolute_url(self):
return reverse("recipes:detail", kwargs={"id": self.id}) # recipes is from url.py app_name
def get_hx_url(self):
return reverse("recipes:hx-detail", kwargs={"id": self.id}) # recipes is from url.py app_name
def get_edit_url(self):
return reverse("recipes:update", kwargs={"id": self.id})
def get_image_upload_url(self):
return reverse("recipes:recipe-ingredient-image-upload", kwargs={"parent_id": self.id})
def get_delete_url(self):
return reverse("recipes:delete", kwargs={"id": self.id})
def get_ingredients_children(self):
return self.recipeingredient_set.all()
def get_instruction_children(self):
return self.recipeinstruction_set.all()
class RecipeIngredient(models.Model):
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
name = models.CharField(max_length=220) # grilled chicken pasta
description = models.TextField(blank=True, null=True)
quantity = models.CharField(max_length=50, blank=True, null=True)
unit = models.CharField(max_length=50, validators=[validate_unit_of_measure], blank=True, null=True)
instructions = models.TextField(blank=True, null=True)
timeStamp = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)
def get_absolute_url(self):
return self.recipe.get_absolute_url() # recipe cannot be none
def get_hx_edit_url(self):
kwargs = {
"parent_id": self.recipe.id,
"id": self.id
}
return reverse("recipes:hx-ingredient-detail", kwargs=kwargs)
def get_delete_url(self):
kwargs = {
"parent_id": self.recipe.id,
"id": self.id
}
return reverse("recipes:ingredient-delete", kwargs=kwargs)
Views.py
#login_required
def recipe_create_view(request):
form = RecipeForm(request.POST or None)
context = {
"form": form,
}
if form.is_valid():
obj = form.save(commit=False)
obj.user = request.user
obj.save()
if request.htmx: # necessary to pass headers from htmx response if we want the django to recognise the htmx change
headers = {
"HX-Redirect": obj.get_absolute_url()
}
return HttpResponse("Created", headers=headers)
# if request.htmx: # could use this but the url doesn't update, stays as create, would need to use HX-Push header & HttpResponse + context somehow
# context = {
# "object": obj
# }
# return render(request, "recipes/partials/detail.html", context)
return redirect(obj.get_absolute_url())
return render(request, "recipes/create.html", context)
#login_required
def recipe_ingredient_update_hx_view(request, parent_id=None, id=None): # this is both create & edit, can create
if not request.htmx:
raise Http404
try:
parent_obj = Recipe.objects.get(id=parent_id, user=request.user)
except:
parent_obj = None
if parent_obj is None:
return HttpResponse("Not Found.")
instance = None
if id is not None:
try:
instance = RecipeIngredient.objects.get(recipe=parent_obj, id=id) # think of this as an object if that helps
except:
instance = None
form = RecipeIngredientForm(request.POST or None, instance=instance)
url = reverse("recipes:hx-ingredient-create", kwargs={"parent_id": parent_obj.id})
if instance:
url = instance.get_hx_edit_url()
context = {
"url": url,
"form": form,
"object": instance
}
if form.is_valid():
new_obj = form.save(commit=False)
if instance is None:
new_obj.recipe = parent_obj
new_obj.save()
context['object'] = new_obj # because it's possible the object/instance in None
return render(request, "recipes/partials/ingredient-inline.html", context)
return render(request, "recipes/partials/ingredient-form.html", context)
forms.py
from django import forms
from .models import Recipe, RecipeIngredient
class RecipeForm(forms.ModelForm):
class Meta:
model = Recipe
fields = ['name', 'image', 'description', 'notes', 'cookTime']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields:
new_data = {
"placeholder": f"Recipe {str(field)}",
"class": "form-control",
}
self.fields[str(field)].widget.attrs.update(new_data)
class RecipeIngredientForm(forms.ModelForm):
class Meta:
model = RecipeIngredient
fields = ['name', 'quantity', 'unit']
urls.py
from django.urls import path
from .views import (
recipe_list_view,
recipe_delete_view,
recipe_create_view,
recipe_update_view,
recipe_detail_hx_view,
recipe_ingredient_update_hx_view,
recipe_ingredient_delete_view,
recipe_ingredient_image_upload_view,
recipe_ingredient_url_scrape_view
)
app_name='recipes' # allows use of recipes:list as a reverse url call
urlpatterns = [
path('', recipe_list_view, name='list'), # index / home / root
path('create/>', recipe_create_view, name='create'),
path('hx/<int:parent_id>/ingredient/<int:id>', recipe_ingredient_update_hx_view, name='hx-ingredient-detail'), #or detail
path('hx/<int:parent_id>/ingredient/', recipe_ingredient_update_hx_view, name='hx-ingredient-create'),
]
create.html
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% load static %}
{% block content %}
<div class="container-fluid px-5">
<h1 class="pb-5">Create Recipe</h1>
<div id="recipe-container">
<form action='.' method="POST" hx-post='.'>
{% csrf_token %}
<div class='row'>
<div class="row d-flex pb-5">
<div class="col-12 col-lg-6 justify-content-center d-flex order-first order-lg-last pictureBox"
style="height: 400px; width:450; border: solid tomato 1px;">
<div class="align-self-center">
{{ form.image|as_crispy_field }}
</div>
</div>
<div class="col-12 col-lg-6 order-lg-first">
<div class="pb-3">{{ form.name|as_crispy_field }}</div>
<div class="pb-3">{{ form.description|as_crispy_field }}</div>
</div>
</div>
<div class="col-12 col-md-6">
{{ form.notes|as_crispy_field }}
</div>
<div class="col-12 col-md-6">
{{ form.cookTime |as_crispy_field }}
</div>
</div>
</div>
<div class='col-12 col-md-4'>
<!-- ADD INGREDIENTS ? -->
</div>
<div class="htmx-indicator">Loading...</div>
<div class="d-flex">
<button class="btn btn-success htmx-inverted-indicator" style='margin-top:10px;' type='submit'>Save</button>
<a class="btn btn-danger" href='{% url "recipes:list" %}'>Delete</a>
</div>
{% if message %}
<p>{{ message }}</p>
{% endif %}
</form>
</div>
</div>
{% endblock content %}
ingredient-form.html
<form action='.' method="POST" hx-post='{% if url %} {{ url }} {% else %} . {{% endif %}' hx-swap='outerHTML'>
{% csrf_token %}
{{ form.as_p}}
<div class="htmx-indicator">Loading...</div>
<button class="htmx-inverted-indicator" style='margin-top:10px;' type='submit' >Save</button>
</form>
ingredient-inline.html
<div class="py-1" id="ingredient-{{object.id}}">
<p>{% if not edit %} <b>{{ object.quantity }} {% if object.unit %} {{ object.unit }} {% endif %}</b> {% else %} {{ object.quantity }} {{ object.unit }} {% endif %} - {{ object.name }}</p>
{% if edit %}
<button class="btn btn-primary" hx-trigger='click' hx-get='{{ object.get_hx_edit_url }}' hx-target="#ingredient-{{object.id}}">Edit</button> <!-- target will replace whole div-->
<button class="btn btn-danger" href='{{ object.get_delete_url }}' hx-post='{{ object.get_delete_url }}' hx-confirm="Are you sure you want to delete {{ object.name }}?" hx-trigger='click' hx-target="#ingredient-{{object.id}}" hx-swap="outerHTML">Delete</button>
{% endif %}
</div>
The key to this problem is using a formset, as you will likely want to save multiple ingredients to the recipe. Django documentation outlines how to use them. Your view would end up looking something like below, allowing you to save the parent model, which will give you the parent instance/primary key to then save the ingredients.
def recipe_create_view(request):
form = RecipeForm(request.POST or None)
RecipeIngredientFormset = formset_factory(RecipeIngredientForm)
formset = RecipeIngredientFormset(request.POST or None)
context = {
"form": form,
"formset": formset,
}
if request.method == "POST":
if form.is_valid() and formset.is_valid():
parent = form.save(commit=False)
parent.user = request.user
parent.save()
#recipe ingredients
for form in formset:
child = form.save(commit=False)
child.recipe = parent
child.save()
In my Blog Django Project I am trying to create a Like Feature, but currently facing the below error:
Reverse for 'post-detail' with no arguments not found. 1 pattern(s) tried: ['blog/(?P<slug>[-a-zA-Z0-9_]+)/$']
What should I do to prevent this error and to return back to the same Post-detail page after pressing the like button?
Here is the urls.py
path('blog/<slug:slug>/', PostDetailView.as_view(), name='post-detail'),
path('blogs/like', like_post, name='like-post'),
Here is the models.py
class Post(models.Model):
liked = models.ManyToManyField(User, default=None, blank=True, related_name='liked')
def num_likes(self):
return self.liked.all().count()
def get_absolute_url(self):
return reverse('blog:post-detail', kwargs={'slug': self.slug})
LIKE_CHOICES = (
('Like', 'Like'),
('Unlike', 'Unlike')
)
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
value = models.CharField(choices=LIKE_CHOICES, default='Like', max_length=10)
date_liked = models.DateTimeField(default=timezone.now)
def __str__(self):
return str(self.post)
Here is the views:
I have made a couple of trials but did not work, I have commented them in the end of the views.py as they returned like_post() missing 1 required positional argument: 'slug'
class PostListView(ListView):
model = Post
template_name = "blog/post_list.html" # <app>/<model>_<viewtype>.html
ordering = ['-date_posted']
context_object_name = 'posts'
paginate_by = 1
class PostDetailView(DetailView):
model = Post
template_name = "blog/post_detail.html" # <app>/<model>_<viewtype>.html
def get(self, request, *args, **kwargs):
res = super().get(request, *args, **kwargs)
self.object.incrementViewCount()
return res
def like_post(request):
user=request.user
if request.method=='POST':
post_id=request.POST.get('post_id')
post_obj= Post.objects.get(id=post_id)
if user in post_obj.liked.all():
post_obj.liked.remove(user)
else:
post_obj.liked.add(user)
like,created=Like.objects.get_or_create(user=user,post_id=post_id)
if not created:
if like.value=='Like':
like.value='Unlike'
else:
like.value='Like'
like.save()
return redirect('blog:post-detail') <------------ Error Showing from Here
#post = get_object_or_404(Post, slug=Post.slug)
#if post.slug != slug:
#return redirect('blog:post-detail', slug=Post.slug)
Here is the template:
<form action="{% url 'blog:like-post' %}" method="POST">
{% csrf_token %}
<input type="hidden" name="post_id" value='{{post.id}}'>
{% if user not in obj.liked.all %}
<button class="ui button positive" type="submit"> Like</button>
{% else %}
<button class="ui button negative" type="submit">Unlike</button>
{% endif %}
<br>
<strong>{{ post.liked.all.count }} Likes</strong>
</form>
redirect('blog:post-detail', slug=post_obj.slug)
how can I retrieve the lesson modules by its parent lesson strictly? e.g if I change to the next lesson where at the same contains a lessonmodule /lesson1/task1 this one shouldn't display since it doesn't belong to lesson2? how can I fix this by only retrieve slugs, content by the lesson attach to?
views
class LessonDetailView(LoginRequiredMixin, View):
login_url = "/account/login/"
def get(self, request, course_slug, lesson_slug, *args, **kwargs):
lesson = get_object_or_404(Lesson.objects.select_related('course'), slug=lesson_slug, course__slug=course_slug)
lessonmodule = get_object_or_404(LessonModule.objects.select_related('lesson'), slug='hello_world')
context = {
'object': lessonmodule,
'previous_lesson': lesson.get_previous_by_created_at,
'next_lesson': lesson.get_next_by_created_at,
}
return render(request, "courses/lesson_detail.html", context)
models
class Lesson(models.Model):
title = models.CharField(max_length=120)
slug = models.SlugField(max_length=25,unique=True)
course = models.ForeignKey(Course, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('lesson-detail',
kwargs={
'course_slug': self.course.slug,
'lesson_slug': self.slug
})
class LessonModule(models.Model):
slug = models.SlugField(unique=True, blank=True, null=True)
content = models.TextField()
lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE)
allowed_memberships = models.ManyToManyField(Membership)
created_at = models.DateTimeField(auto_now_add=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, blank=True)
def __str__(self):
return self.slug
template
{% block content %}
<div class='container'>
<h1>Lesson Detail View</h1>
<div class='row'>
<div class='col-sm-6 col-md-6'>
{% if object is not None %}
<h3>{{ object.title }}</h3>
<p>{{ object.course.description }}</p>
{{object}}
{% if previous_lesson %}
Back
{% endif %}
{% if next_lesson %}
Next
{% endif %}
{% else %}
<h3>Upgrade membership</h3>
<p>To view this course you'll need to upgrade your membership</p>
<br>
<hr>
{% endif %}
</div>
</div>
</div>
{% endblock content %}
As I can see here, you can have multiple LessonModule for a single Lesson due to one-to-many relation between Lesson and LessonModule(ForeignKey relation basically). You can fetch all the LessonModules like this(using reverse query):
# view
def get(self, request, course_slug, lesson_slug, *args, **kwargs):
lesson = get_object_or_404(Lesson.objects.select_related('course').prefetch_related('lessonmodule_set'), slug=lesson_slug, course__slug=course_slug)
context = {
'object': lesson,
'previous_lesson': lesson.get_previous_by_created_at,
'next_lesson': lesson.get_next_by_created_at,
}
return render(request, "courses/lesson_detail.html", context)
# template
{% for lesson_module in object.lessonmodule_set.all %}
{{ lesson_module.slug }}
{% endfor %}
I am just sending the Lesson object to template, and using reverse query in template to get LessonModule objects.
I have a form which creates a new category. Previously, the form was in a different template which worked fine but since it's only a simple form I have decided to render it in modal form instead of redirecting to a different page.
The user can add a new category, however the success message and the page rendering after the form submit is not shown. It only shows up if you refresh the page. The response message is 302.
I've done similar method with other forms which worked perfectly fine.
forms.py
class CategoryModelForm(forms.ModelForm):
def clean_name(self):
print(self.cleaned_data['name'])
name = self.cleaned_data['name']
try:
Category.objects.get(name__iexact=name)
except ObjectDoesNotExist:
return name
raise forms.ValidationError('Category Name already exists.')
class Meta:
model = Category
fields = ['name']
views.py
#method_decorator(login_required, name='dispatch')
class CategoryView(TemplateView):
template_name = 'content/category_list.html'
def get_context_data(self, **kwargs):
context = super(CategoryView, self).get_context_data(**kwargs)
categories = Category.objects.all()
user = self.request.user
category_list = []
for category in categories:
article_count = category.article_count(user)
include = category.show or user.usertype_is_staff() or user.is_superuser
requested_by = category.requested_by if category.requested_by else ''
cat = {
'reference': category.pk,
'name': category.name,
'show': category.show,
'article_count': article_count,
'has_articles': article_count > 0,
'requested_by': requested_by,
'requested_by_name': requested_by.profile.full_name if requested_by and requested_by.profile.full_name
else '-'
}
include and category_list.append(cat)
context['categories'] = category_list
context['form'] = CategoryModelForm(self.request.POST or None)
return context
def post(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
if context['form'].is_valid():
context['form'].save()
messages.success(request, 'Successfully created new category.')
return redirect('content:category')
return super(CategoryView, self).render_to_response(context)
category_list.html
<div id="newCategory" data-id="new-account" class="modal fade bd-example-modal-lg"
tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="syn-breadcrumb">
<div class="syndicator-form-container">
<form class="syndicator-form" action="{% url 'content:category' %}"
method="post">
{% csrf_token %}
<div class="">
<h3 class="lighter-weight">
{% if user.usertype_is_supplier %}
Request New Category
{% else %}
Add New Category
{% endif %}
</h3>
</div>
<div class="form-fields">
<div class="non-field-errors">
{{ form.non_field_errors }}
</div>
<div id="{{ form.name.name }}" class="d-flex flex-column fields">
<div class="lighter-weight"><label for="id_name">Name</label></div>
<div>{{ form.name }}</div>
<div class="field-errors">{{ form.name.errors }}</div>
</div>
</div>
<div class="submit-button">
<button type="submit" class="btn btn-primary form-control">{% trans 'Submit' %}</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
I want the page to be redirected to an updated list of the categories after the form submit with the success message. As well as show the error message if the category name already exists or if the fields re empty.
You are using self.request instead of request even though request is already passed in post method
def post(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
context['form'] = CategoryModelForm(request.POST or None) # use request.POST
I would rather suggest you to use a FormView or rather a generic view. (docs). You won't need to handle the form by yourself.
#method_decorator(login_required, name='dispatch')
class CategoryView(FormView):
template_name = 'content/category_list.html'
form = CategoryModelForm
success_url = reverse("content:category")
def form_valid(self, form):
self.obj = form.save(commit=True)
messages.success(self.request, 'Successfully created new category.')
return super(CategoryView, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(CategoryView, self).get_context_data(**kwargs)
categories = Category.objects.all()
user = self.request.user
category_list = []
for category in categories:
article_count = category.article_count(user)
include = category.show or user.usertype_is_staff() or user.is_superuser
requested_by = category.requested_by if category.requested_by else ''
cat = {
'reference': category.pk,
'name': category.name,
'show': category.show,
'article_count': article_count,
'has_articles': article_count > 0,
'requested_by': requested_by,
'requested_by_name': requested_by.profile.full_name if requested_by and requested_by.profile.full_name
else '-'
}
include and category_list.append(cat)
context['categories'] = category_list
# form will be automatically added to context
I have a problem when saving/creating new post for blog.
I already have Post model and each post has it's own category. so I have Category model too. In CreateView template I already got all categories from DB and displayed in select/option tag. The issue is I want to save category_id when I create new post. But I don't know how? How can I say if form POSTED get category_id and save it for Post model that has category_id field?
View:
class PostCreateForm(LoginRequiredMixin, CreateView):
model = Post
fields = ['title', 'short_text', 'long_text', 'post_pic']
def get_context_data(self, **kwargs):
context = super(PostCreateForm, self).get_context_data(**kwargs)
context['categories'] = Category.objects.all().order_by('id')
return context
def form_valid(self, form, **kwargs):
form.instance.author = self.request.user
return super().form_valid(form)
Model:
class Category(models.Model):
title = models.CharField(max_length=255)
def __str__(self):
return self.title
class Post(models.Model):
title = models.CharField(max_length=255)
short_text = models.TextField()
long_text = models.TextField()
post_pic = models.ImageField(default="post_pic.jpg",
blank=False, upload_to='post_pics')
date_published = models.DateTimeField(default=timezone.now())
date_upadated = models.DateTimeField(auto_now=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.ForeignKey(Category, default=None,
on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})`
post_form.html
{% extends 'blog/base.html' %}
{% load crispy_forms_tags %}
{% block title_head %}
New Post
{% endblock title_head %}
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4 pb-2">New Post</legend>
{{ form|crispy }}
<select class="form-control" name="category">
{% for category in categories %}
<option value="{{ category.id }}">{{ category }}</option>
{% endfor %}
</select>
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-outline-info">Post</button>
</div>
</form>
{% endblock content %}
There are a few ways to achieve this. Here is the simplest:
If you expect the Catagories to remain the same then you can hard code them and use a CharField with the choices= keyword on your Post model.
class Post(models.Model):
CATEGORY_CHOICES = (
('Horror', 'Horror'),
('Romance', 'Romance'),
('Comedy', 'Comedy'),
)
category = models.CharField(choices=CATEGORY_CHOICES)
Then all you need to do is add 'category' to your fields list in the CreateView.
Side Note You should probs rename your CreateView it's a view not a form. This may cause confusion.
Solved!
we have access category in list of fields so it's useless to fetch all categories then displaying them in select-option tag in html page. just add category field in list of fields
Change PostCreateForm
change it from this
class PostCreateForm(LoginRequiredMixin, CreateView):
model = Post
fields = ['title', 'short_text', 'long_text', 'post_pic']
def get_context_data(self, **kwargs):
context = super(PostCreateForm, self).get_context_data(**kwargs)
context['categories'] = Category.objects.all().order_by('id')
return context
def form_valid(self, form, **kwargs):
form.instance.author = self.request.user
return super().form_valid(form)
to this
class PostCreateForm(LoginRequiredMixin, CreateView):
model = Post
fields = ['title', 'short_text', 'long_text', 'post_pic', 'category']
def get_context_data(self, **kwargs):
context = super(PostCreateForm, self).get_context_data(**kwargs)
return context
def form_valid(self, form, **kwargs):
form.instance.author = self.request.user
return super().form_valid(form)