Skip to content

Commit 8f86ce8

Browse files
add the ability to update posts
1 parent 4b4fa8e commit 8f86ce8

File tree

9 files changed

+125
-24
lines changed

9 files changed

+125
-24
lines changed

post/forms.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33

44
from django_summernote.fields import SummernoteTextFormField
55

6-
from imagekit.forms import ProcessedImageField
7-
from imagekit.processors import SmartResize
8-
96
from .models import Post
107
from .validators import LetterUsernameValidator
118

@@ -127,3 +124,17 @@ class Meta:
127124
model = Post
128125
fields = ('title', 'description', 'image_thumbnail', 'content', 'tags')
129126

127+
128+
class EditPostForm(CreatePostForm):
129+
"""Форма для редактирования постов"""
130+
131+
def __init__(self, *args, **kwargs):
132+
self.post = kwargs.pop('post', None)
133+
super().__init__(*args, **kwargs)
134+
self.fields['image_thumbnail'].required = False
135+
136+
def clean(self):
137+
title = self.cleaned_data['title']
138+
if Post.objects.filter(title=title).exists():
139+
if Post.objects.get(title=title) != self.post:
140+
raise forms.ValidationError('Пост с таким названием уже существует')

post/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class Post(models.Model):
1616
format='JPEG',
1717
options={'quality': 60}
1818
)
19-
slug = models.SlugField(unique=True)
19+
slug = models.SlugField(unique=True, max_length=127)
2020
tags = models.ManyToManyField('Tag', verbose_name='Tags')
2121
author = models.ForeignKey('Profile', verbose_name='Автор', on_delete=models.PROTECT)
2222
pub_date = models.DateTimeField(auto_now_add=True)

post/templates/post/base.html

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
{% load static %}
66
<meta charset="utf-8">
77
<meta name="viewport" content="width=device-width, initial-scale=1">
8-
{% block description %}
9-
<meta name="description" content="">
10-
{% endblock %}
8+
<meta name="description" content="{% block description %}{% endblock %}">
119
<meta name="generator" content="Hugo 0.88.1">
1210
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
1311
<title>

post/templates/post/create_post.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<a class="ms-2 text-decoration-none">@{{ profile.user.username }}</a>
1414
</span>
1515
<hr>
16-
<p class="text-secondary fs-5 text-center"><strong>Создание поста</strong></p>
16+
<p class="text-secondary fs-5 text-center"><strong>Создать пост</strong></p>
1717
<hr>
1818
<div style="width: 900px">
1919
<form action="" enctype="multipart/form-data" method="post">
@@ -22,7 +22,7 @@
2222
<br>
2323
<br>
2424
<div class="d-grid gap-2 col-6 mx-auto">
25-
<input type="submit" class="btn btn-success btn-lg" value="Опубликовать">
25+
<input type="submit" class="btn btn-primary btn-lg" value="Опубликовать">
2626
</div>
2727
</form>
2828
</div>

post/templates/post/edit_post.html

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{% extends 'post/base.html' %}
2+
{% load crispy_forms_tags %}
3+
{% block title %}
4+
{{ profile.user.username }} | Ukiblog
5+
{% endblock %}
6+
{% block categories %}
7+
{% endblock %}
8+
{% block main %}
9+
<div class="card" style="width: 1000px; margin: 100px 500px 300px 450px; padding: 30px 30px">
10+
<div class="card-body">
11+
<span class="text-start fs-1">
12+
<img src="{{ profile.avatar_thumbnail.url }}" alt="" width="100" height="100" class="rounded-circle me-2">
13+
<a class="ms-2 text-decoration-none">@{{ profile.user.username }}</a>
14+
</span>
15+
<hr>
16+
<p class="text-secondary fs-5 text-center"><strong>Редактировать пост</strong></p>
17+
<hr>
18+
<div style="width: 900px">
19+
<form action="" enctype="multipart/form-data" method="post">
20+
{% csrf_token %}
21+
{{ form|crispy|safe}}
22+
<br>
23+
<br>
24+
<div class="d-grid gap-2 col-6 mx-auto">
25+
<input type="submit" class="btn btn-primary btn-lg" value="Редактировать">
26+
</div>
27+
</form>
28+
</div>
29+
</div>
30+
</div>
31+
{% endblock %}

post/templates/post/post_detail.html

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{% extends 'post/base.html' %}
22
{% block title %}
3-
{{ post.title }}
3+
{{ post.title }}
44
{% endblock %}
55
{% block description %}
6-
<meta name="description" content="{{ post.description_for_search_engines }}">
6+
{{ post.description_for_search_engines }}
77
{% endblock %}
88
{% block main %}
9-
<main class="px-3 text-dark" style="margin-left: 450px; width: 900px;">
9+
<main class="px-3 text-dark" style="margin-left: 450px; width: 900px;">
1010
<div class="card text-center">
1111
<div class="card-header">
1212
<a href="#" class="text-decoration-none text-dark" style="font-weight: 600">
@@ -15,26 +15,33 @@
1515
</a>
1616
<span class="text-muted">
1717
{{ post.pub_date|date:"H:i d.m.Y" }}
18-
{% if post.pub_date != post.edit_date %}
18+
{% if post.pub_date != post.edit_date %}
1919
(ред.
2020
{% if post.pub_date|date:"d.m.Y" == post.edit_date|date:"d.m.Y" %}
21-
в {{ post.edit_date|date:"H:i" }}
21+
в {{ post.edit_date|date:"H:i" }}
2222
{% else %}
23-
{{ post.edit_date|date:"H:i d.m.Y" }}
23+
{{ post.edit_date|date:"H:i d.m.Y" }}
2424
{% endif %}
2525
)
26-
{% endif %}
26+
{% endif %}
2727
</span>
28+
{% if post.author.user == user %}
29+
<a href="{% url 'post:edit_post' slug=post.slug %}" class="text-decoration-none">
30+
<button type="button" class="btn btn-outline-primary btn-lg" style="margin-left: 200px">
31+
Редактировать
32+
</button>
33+
</a>
34+
{% endif %}
2835
</div>
2936
<div class="card-body">
3037
<h2 class="card-title text-dark">
3138
{{ post.title }}
3239
</h2>
33-
<img src="{{ post.image_thumbnail.url }}" width=600px style="margin: 15px 0;">
40+
<img src="{{ post.image_thumbnail.url }}" width=600px style="margin: 15px 0;" alt="">
3441
<hr>
3542
<div class="text-start">
3643
{% autoescape off %}
37-
<p class="card-text">{{ post.content }}</p>
44+
<p class="card-text">{{ post.content }}</p>
3845
{% endautoescape %}
3946
</div>
4047
</div>

post/templates/post/profile.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
{% block categories %}
66
{% endblock %}
77
{% block main %}
8-
<div class="card" style="width: 800px; margin: 100px 600px 300px 500px; padding: 30px 30px">
8+
<div class="card" style="width: 800px; margin: 0 600px 300px 500px; padding: 30px 30px">
99
<div class="card-body">
1010
<span class="text-start fs-1">
1111
<img src="{{ main_profile.avatar_thumbnail.url }}" alt="" width="100" height="100" class="rounded-circle me-2">

post/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
ProfileView,
1212
EditProfileView,
1313
CreatePostView,
14+
EditPostView,
1415
)
1516

1617
app_name = 'post'
@@ -24,4 +25,5 @@
2425
path('profile/<slug:slug>', ProfileView.as_view(), name='profile'),
2526
path('profile/<slug:slug>/edit', EditProfileView.as_view(), name='edit_profile'),
2627
path('create_post', CreatePostView.as_view(), name='create_post'),
28+
path('edit_post/<slug:slug>', EditPostView.as_view(), name='edit_post'),
2729
]

post/views.py

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
from slugify import slugify
2+
13
from django.shortcuts import render, redirect
24
from django.urls import reverse, reverse_lazy
35
from django.utils import timezone
4-
from django.utils.text import slugify
56
from django.views import View, generic
67
from django.contrib.auth import login, authenticate
78
from django.contrib.auth.models import AnonymousUser, User
@@ -10,7 +11,7 @@
1011

1112
from .models import Post, Tag, Profile
1213
from .mixins import DefaultContextMixin
13-
from .forms import LoginForm, RegistrationForm, EditProfileForm, CreatePostForm
14+
from .forms import LoginForm, RegistrationForm, EditProfileForm, CreatePostForm, EditPostForm
1415

1516

1617
class BaseView(DefaultContextMixin, generic.ListView):
@@ -28,7 +29,9 @@ class PostDetailView(DefaultContextMixin, generic.DetailView):
2829
model = Post
2930

3031
def get_context_data(self, **kwargs):
31-
return super().get_context_data(self.request, **kwargs)
32+
context = super().get_context_data(self.request, **kwargs)
33+
context['user'] = self.request.user
34+
return context
3235

3336

3437
class TagDetailView(DefaultContextMixin, generic.DetailView):
@@ -44,6 +47,7 @@ def get_context_data(self, **kwargs):
4447

4548
class LoginView(View):
4649
"""Авторизация"""
50+
4751
def get(self, *args, **kwargs):
4852
form = LoginForm()
4953
context = {
@@ -72,6 +76,7 @@ def post(self, *args, **kwargs):
7276

7377
class RegistrationView(View):
7478
"""Регистрация"""
79+
7580
def get(self, *args, **kwargs):
7681
form = RegistrationForm()
7782
context = {
@@ -122,6 +127,7 @@ def get_context_data(self, **kwargs):
122127

123128
class EditProfileView(View):
124129
"""Настройки профиля"""
130+
125131
def get(self, *args, **kwargs):
126132
if isinstance(self.request.user, AnonymousUser):
127133
messages.warning(self.request, 'У вас недостаточно прав!')
@@ -168,7 +174,7 @@ def post(self, *args, **kwargs):
168174

169175

170176
class CreatePostView(DefaultContextMixin, generic.CreateView):
171-
"""Создание поста"""
177+
"""Создать пост"""
172178
model = Post
173179
form_class = CreatePostForm
174180
template_name = 'post/create_post.html'
@@ -177,7 +183,7 @@ def get(self, *args, **kwargs):
177183
if isinstance(self.request.user, AnonymousUser) or not Profile.objects.get(user=self.request.user).author:
178184
messages.warning(self.request, 'У вас недостаточно прав!')
179185
return redirect(reverse('post:base'))
180-
super().get(*args, **kwargs)
186+
return super().get(*args, **kwargs)
181187

182188
def form_valid(self, form):
183189
post = Post.objects.create(
@@ -193,7 +199,53 @@ def form_valid(self, form):
193199
edit_date=timezone.now(),
194200
)
195201
post.tags.add(*form.cleaned_data['tags'])
202+
messages.success(
203+
self.request,
204+
f'Ваш пост успешно создан с:\nАдминистрация проверит его и опубликует!'
205+
)
196206
return redirect(reverse('post:profile', kwargs={'slug': slugify(self.request.user.username)}))
197207

198208
def get_context_data(self, **kwargs):
199209
return super().get_context_data(self.request)
210+
211+
212+
class EditPostView(DefaultContextMixin, View):
213+
"""Редактировать пост"""
214+
215+
def get(self, *args, **kwargs):
216+
if isinstance(self.request.user, AnonymousUser) or Post.objects.get(
217+
slug=kwargs['slug']).author.user != self.request.user:
218+
messages.warning(self.request, 'У вас недостаточно прав!')
219+
return redirect(reverse('post:base'))
220+
data = model_to_dict(Post.objects.get(slug=kwargs['slug']))
221+
form = EditPostForm(initial=data)
222+
context = {
223+
'form': form,
224+
}
225+
context.update(self.get_context_data(self.request, **kwargs))
226+
return render(self.request, 'post/edit_post.html', context)
227+
228+
def post(self, *args, **kwargs):
229+
post = Post.objects.get(slug=kwargs['slug'])
230+
form = EditPostForm(self.request.POST, self.request.FILES, post=post)
231+
if form.is_valid():
232+
post.title = form.cleaned_data['title']
233+
post.slug = slugify(form.cleaned_data['title'])
234+
post.content = form.cleaned_data['content']
235+
post.description = form.cleaned_data['description']
236+
post.description_for_search_engines = form.cleaned_data['description']
237+
post.edit_date = timezone.now()
238+
post.tags.add(*form.cleaned_data['tags'])
239+
if form.cleaned_data['image_thumbnail']:
240+
post.image_thumbnail = form.cleaned_data['image_thumbnail']
241+
post.save()
242+
messages.success(
243+
self.request,
244+
f'Ваш пост успешно обновлен с:\nАдминистрация проверит его и опубликует!'
245+
)
246+
return redirect(reverse('post:profile', kwargs={'slug': slugify(self.request.user.username)}))
247+
context = {
248+
'form': form,
249+
}
250+
context.update(self.get_context_data(self.request, **kwargs))
251+
return render(self.request, 'post/edit_post.html', context)

0 commit comments

Comments
 (0)