Приветствую.
Снова неделя пролетела, а вроде бы ещё вчера было воскресенье. Пора отдыхать!
Фильм на сегодня: Голограмма для короля (2016).
Краткий синопсис: Алан Клей - муж, отец, бизнесмен. Но его бизнес терпит крах, его брак трещит по швам, и он не знает, где взять деньги на оплату обучения дочери. Чтобы избежать банкротства и разорвать замкнутый круг, Клей отправляется в Саудовскую Аравию, где он надеется продвинуть свой дерзкий технологический проект. Во время томительного ожидания встречи с королем Алан познает скрытые тайны арабского мира, которые преображают реальность, подобно голограмме. Никто не подозревал, чем обернется это путешествие к Красному морю…
Если у вас есть подписка КП, то смотреть можно тут: https://www.kinopoisk.ru/film/771067/
Если подписки нет, то тут: https://www.sspoisk.ru/film/771067/
А как провели неделю вы?
Снова неделя пролетела, а вроде бы ещё вчера было воскресенье. Пора отдыхать!
Фильм на сегодня: Голограмма для короля (2016).
Краткий синопсис: Алан Клей - муж, отец, бизнесмен. Но его бизнес терпит крах, его брак трещит по швам, и он не знает, где взять деньги на оплату обучения дочери. Чтобы избежать банкротства и разорвать замкнутый круг, Клей отправляется в Саудовскую Аравию, где он надеется продвинуть свой дерзкий технологический проект. Во время томительного ожидания встречи с королем Алан познает скрытые тайны арабского мира, которые преображают реальность, подобно голограмме. Никто не подозревал, чем обернется это путешествие к Красному морю…
Если у вас есть подписка КП, то смотреть можно тут: https://www.kinopoisk.ru/film/771067/
Если подписки нет, то тут: https://www.sspoisk.ru/film/771067/
А как провели неделю вы?
Django 34.1. Простой профиль пользователя - страница профиля
Что у нас уже есть?
- Регистрация пользователя
- Авторизация пользователя
- Сброс пароля
Следующим шагом необходимо реализовать профиль пользователя.
Я знаю три способа реализации личного кабинета / профиля пользователя:
- Простой - страничка с доступной из стандартной модели пользователя информацией, а также, например, со списком постов пользователя, его комментариями и другими данными, где пользователь указан в модели.
- Средний - создание дополнительной модели профиля. В этой модели указываются дополнительные поля, методы и прочее, которых нет в стандартной модели.
- Сложный - создание собственной модели пользователя, основываясь на базовом классе или описывая всё с нуля, если это необходимо.
Поскольку у всех разные требования и необходимости, я хочу рассмотреть все три способа, а у вас будет представление о способах реализации и можно будет выбрать наиболее подходящий.
Что у нас уже есть?
- Регистрация пользователя
- Авторизация пользователя
- Сброс пароля
Следующим шагом необходимо реализовать профиль пользователя.
Я знаю три способа реализации личного кабинета / профиля пользователя:
- Простой - страничка с доступной из стандартной модели пользователя информацией, а также, например, со списком постов пользователя, его комментариями и другими данными, где пользователь указан в модели.
- Средний - создание дополнительной модели профиля. В этой модели указываются дополнительные поля, методы и прочее, которых нет в стандартной модели.
- Сложный - создание собственной модели пользователя, основываясь на базовом классе или описывая всё с нуля, если это необходимо.
Поскольку у всех разные требования и необходимости, я хочу рассмотреть все три способа, а у вас будет представление о способах реализации и можно будет выбрать наиболее подходящий.
Начнём с самого простого варианта.
Мы реализуем:
- Страницу профиля. На ней будет информация о пользователе и список его постов, кнопка перехода на страницу настроек и кнопка перехода ко всем постам пользователя. Для этого нам надо будет сделать представление и шаблон.
- Страницу настроек профиля. На ней будет две формы: со сменой имени пользователя и email, а так же со сменой пароля. Для этого нам надо будет сделать представление, шаблон и две формы.
Представление страницы профиля.
Напишем простое представление, которое будет передавать в шаблон объект и посты пользователя.
Откроем файл
Создадим класс
В нём прописываем единственное поле
Ниже переопределяем метод
В нём мы получаем объект класса
Получение объекта оборачиваем в
Записываем в контекст объект пользователя, список его последних пяти постов и заголовок страницы.
Код представления:
**Шаблон страницы профиля.**
В директории с шаблонами приложения создадим новый файл
Внутри разделим его на две части:
- В левой будет список постов и кнопка (пока заглушка) для перехода на страницу всех постов пользователя.
- В правой будет информация о пользователе. На данный момент, это имя пользователя (username), имя и фамилия (если указаны в профиле), а также кнопка для перехода на страницу изменения профиля (пока тоже заглушка).
Мы реализуем:
- Страницу профиля. На ней будет информация о пользователе и список его постов, кнопка перехода на страницу настроек и кнопка перехода ко всем постам пользователя. Для этого нам надо будет сделать представление и шаблон.
- Страницу настроек профиля. На ней будет две формы: со сменой имени пользователя и email, а так же со сменой пароля. Для этого нам надо будет сделать представление, шаблон и две формы.
Представление страницы профиля.
Напишем простое представление, которое будет передавать в шаблон объект и посты пользователя.
Откроем файл
views.py в приложении user_app.Создадим класс
UserProfileView, унаследованный от TemplateView.В нём прописываем единственное поле
template_name, указывающее на файл шаблона.Ниже переопределяем метод
get_context_data.В нём мы получаем объект класса
User, полученный из переданного в адресной строке имени пользователя и записываем в переменную.Получение объекта оборачиваем в
try-except, в случае, если передано некорректное или отсутствующее в базе имя пользователя, вместо страницы с ошибкой получения данных, вернулась страница ошибки 404 (до написания собственных страниц ошибок, мы тоже дойдём.).Записываем в контекст объект пользователя, список его последних пяти постов и заголовок страницы.
Код представления:
from django.contrib.auth.models import User
from django.views.generic import TemplateView
from django.shortcuts import get_object_or_404
from django.http import Http404
from blog.models import PostModel
class UserProfileView(TemplateView):
template_name = 'user_app/profile_page.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
try:
user = get_object_or_404(User, username=self.kwargs.get('username'))
except User.DoesNotExist:
raise Http404("Пользователь не найден")
context['user_profile'] = user
context['user_posts'] = PostModel.post_manager.filter(author=user)[:5]
context['title'] = f'Профиль пользователя {user}'
return context
**Шаблон страницы профиля.**
В директории с шаблонами приложения создадим новый файл
profile_page.html.Внутри разделим его на две части:
- В левой будет список постов и кнопка (пока заглушка) для перехода на страницу всех постов пользователя.
- В правой будет информация о пользователе. На данный момент, это имя пользователя (username), имя и фамилия (если указаны в профиле), а также кнопка для перехода на страницу изменения профиля (пока тоже заглушка).
Код шаблона:
Ссылка на профиль в шапке и в карточке поста.
Теперь добавим ссылку на профиль в шапку сайта.
Откроем файл
Также добавим ссылку в карточку поста или в сам пост:
В первом случае, мы передаём ключевой аргумент
URL-паттерн страницы профиля.
Последнее, что осталось сделать, это прописать URL-паттерн.
Открываем файл
Готово. Теперь у нас есть простая страница профиля. В следующем посте сделаем страницу настроек и страницу всех постов.
Файлы к посту, можно получить в боте по коду: 764197
Пост на сайте.
Поддержать канал.
{% extends 'blog/base.html' %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<div class="container mt-3">
<h2>Профиль пользователя {{ user_profile }}</h2>
<hr>
<div class="row">
<div class="col-xl-8 сol-sm-12">
<h3 class="mb-3">Последние посты:</h3>
{% for post in user_posts %}
<div class="row">
<div class="col-lg-3 col-sm-12 d-flex align-items-center">
<img src="{{ post.image.url }}" alt="{{ post.title }}" class="img-fluid">
</div>
<div class="col-lg-9 col-sm-12">
<h4 class="head2"><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></h4>
<div class="mb-3">
<p class="lead"><a
href="{{ post.category.get_absolute_url }}">{{ post.category }}</a>
| {{ post.publish | date:"d F Y" }} |
Просмотров: {{ post.views }}</p>
</div>
{{ post.short_body | safe }}
</div>
</div>
<hr class="m-1">
{% endfor %}
<div class="text-center mt-3">
<a class="btn btn-primary my-btn mb-3" href="#">Все посты {{ user_profile }}</a>
</div>
</div>
<div class="col-xl-4 col-sm-12 border border-start border-0">
<h3 class="mb-3">Информация:</h3>
<p>
<b>Имя пользователя:</b> {{ user_profile }}
{% if user_profile.first_name %}
<br>
<b>Имя:</b> {{ user_profile.first_name }}
{% endif %}
{% if user_profile.last_name %}
<br>
<b>Фамилия:</b> {{ user_profile.last_name }}</p>
{% endif %}
{% if user_profile == user %}
<a class="btn btn-primary my-btn me-1" href="#">Настройки профиля</a>
{% endif %}
</div>
</div>
</div>
{% endblock %}Ссылка на профиль в шапке и в карточке поста.
Теперь добавим ссылку на профиль в шапку сайта.
Откроем файл
header.html и там, где у нас кнопка "выход", выше добавляем "профиль":<li>
<a class="dropdown-item dd-item-color" href="{% url 'user_app:user_profile' username=user.username %}">Профиль</a>
</li>
Также добавим ссылку в карточку поста или в сам пост:
<a href="{% url 'user_app:user_profile' username=post.author %}">{{ post.author }}</a>В первом случае, мы передаём ключевой аргумент
username текущего авторизованного пользователя, а во втором случае, берём его из поля author у поста.URL-паттерн страницы профиля.
Последнее, что осталось сделать, это прописать URL-паттерн.
Открываем файл
urls.py в директории приложения user_app и в список urlpatterns добавляем новую строку:path('<str:username>/', views.UserProfileView.as_view(), name='user_profile'),Готово. Теперь у нас есть простая страница профиля. В следующем посте сделаем страницу настроек и страницу всех постов.
Файлы к посту, можно получить в боте по коду: 764197
Пост на сайте.
Поддержать канал.
👍3
А достаточно ли ты хорош чтобы иметь синдром самозванца?
Anonymous Poll
25%
Я - Топ!
16%
Да
59%
Нет, но да
Скинули тут занятную статейку переложения программистов на классы в D&D.
https://habr.com/ru/companies/domclick/articles/517736/
Не могу определиться, я Варвар или Воин или мультикласс))
https://habr.com/ru/companies/domclick/articles/517736/
Не могу определиться, я Варвар или Воин или мультикласс))
Django 34.2. Простой профиль пользователя - страница настроек
В предыдущем посте, мы сделали страницу профиля, теперь надо сделать страницу настроек пользователя.
На этой странице пользователь сможет изменить свои данные и поменять пароль.
Также сделаем страницу со всеми постами пользователя.
В процессе напишем две формы, два представления и два шаблона.
Работать будем с файлами в директории приложения
Формы для страницы настроек.
Откроем файл
У нас будет две формы:
- Форма изменения данных пользователя - это имя пользователя (username), email, имя и фамилия.
- Форма смены пароля.
Форма изменения данных.
Это типовая форма модели.
Создадим класс
Описываем четыре поля, добавляя названия полей и стили:
В подклассе
В предыдущем посте, мы сделали страницу профиля, теперь надо сделать страницу настроек пользователя.
На этой странице пользователь сможет изменить свои данные и поменять пароль.
Также сделаем страницу со всеми постами пользователя.
В процессе напишем две формы, два представления и два шаблона.
Работать будем с файлами в директории приложения
user_app. Приступим.Формы для страницы настроек.
Откроем файл
forms.py в директории приложения user_app.У нас будет две формы:
- Форма изменения данных пользователя - это имя пользователя (username), email, имя и фамилия.
- Форма смены пароля.
Форма изменения данных.
Это типовая форма модели.
Создадим класс
UserInfoForm, унаследованный от forms.ModelForm.Описываем четыре поля, добавляя названия полей и стили:
username, email, first_name, last_name.В подклассе
Meta указываем модель User и вышеупомянутые поля.Код формы:
Форма изменения пароля.
Форму смены пароля писать с нуля не будем, т.к. Django предоставляет встроенную форму
Мы всего лишь переопределим поля, добавив стили форме.
Создадим класс
Код формы:
Представление страницы настроек.
Достаточно сложное и объёмно представление.
Нам надо передать на страницу две формы, а затем обрабатывать их независимо друг от друга.
Помимо того, что страница должна быть доступна только авторизованному пользователю, она также должна быть доступна только тому пользователю, чья страница настроек открыта.
Например, у нас есть маршрут
Откроем файл
Создадим класс
- От класса
- От уже знакомого нам класса
Прописываем единственное поле
Далее у нас будет переопределено три метода:
Первым мы переопределим метод
Метод `dispatch()` - это один из ключевых методов в классовых представлениях Django. Он является частью жизненного цикла обработки запросов и играет важную роль в определении того, какой метод (GET, POST, PUT, DELETE и т. д.) должен обрабатывать входящий HTTP-запрос.
class UserInfoForm(forms.ModelForm):
username = forms.CharField(
max_length=150,
label='Имя пользователя (username)',
widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Введите имя пользователя'
})
)
email = forms.EmailField(
widget=forms.EmailInput(attrs={
'class': 'form-control',
'placeholder': 'Введите email'
})
)
first_name = forms.CharField(
max_length=150,
label='Имя',
required=False,
widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Введите ваше имя'
})
)
last_name = forms.CharField(
max_length=150,
label='Фамилия',
required=False,
widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Введите вашу фамилию'
})
)
class Meta:
model = User
fields = ['username', 'email', 'first_name', 'last_name']
Форма изменения пароля.
Форму смены пароля писать с нуля не будем, т.к. Django предоставляет встроенную форму
PasswordChangeForm.Мы всего лишь переопределим поля, добавив стили форме.
Создадим класс
UserPasswordForm, унаследованный от PasswordChangeForm и пропишем три поля: old_password, new_password1, new_password2.Код формы:
class UserPasswordForm(PasswordChangeForm):
old_password = forms.CharField(
max_length=128,
label='Старый пароль',
widget=forms.PasswordInput(attrs={
'class': 'form-control',
'placeholder': 'Введите старый пароль'
})
)
new_password1 = forms.CharField(
max_length=128,
label='Новый пароль',
help_text=password_validation.password_validators_help_text_html(),
widget=forms.PasswordInput(attrs={
'class': 'form-control',
'placeholder': 'Введите новый пароль'
})
)
new_password2 = forms.CharField(
max_length=128,
label='Подтверждение нового пароля',
widget=forms.PasswordInput(attrs={
'class': 'form-control',
'placeholder': 'Повторите новый пароль'
})
)
Представление страницы настроек.
Достаточно сложное и объёмно представление.
Нам надо передать на страницу две формы, а затем обрабатывать их независимо друг от друга.
Помимо того, что страница должна быть доступна только авторизованному пользователю, она также должна быть доступна только тому пользователю, чья страница настроек открыта.
Например, у нас есть маршрут
/user/testuser/settings, где testuser это имя пользователя. И если по этому адресу перейдёт testuser, то он увидит настройки, но если другой пользователь откроет эту страницу, то должна быть ошибка 403 Forbidden.Откроем файл
views.py.Создадим класс
UserSettingsView, в этот раз у нас будет два наследования:- От класса
LoginRequiredMixin, проверяющего авторизован пользователь или нет.- От уже знакомого нам класса
TemplateView.Прописываем единственное поле
template_name с указанием файла шаблона.Далее у нас будет переопределено три метода:
Первым мы переопределим метод
dispatch(). С ним мы ещё не сталкивались. Метод `dispatch()` - это один из ключевых методов в классовых представлениях Django. Он является частью жизненного цикла обработки запросов и играет важную роль в определении того, какой метод (GET, POST, PUT, DELETE и т. д.) должен обрабатывать входящий HTTP-запрос.
`dispatch()` работает следующим образом:
1. Когда клиентский запрос поступает на представление, Django вызывает метод `dispatch()` этого представления.
2. `dispatch()` анализирует метод HTTP запроса (GET, POST, PUT, DELETE и т. д.), который пришел от клиента.
3. В зависимости от метода запроса, `dispatch()
4. После обработки запроса соответствующим методом, `dispatch()` возвращает HTTP-ответ.
В нашем методе, мы проверяем, является ли пользователь переданный в адресной строке текущим авторизованным пользователем.
Если является - вызываем метод
Вторым переопределённым методом будет
В этом методе мы передаём две формы и т.к. у нас формы моделей, нам при их сохранении в переменную, в качестве аргумента необходимо передать объект модели, с которым будет работать форма. Если этого не сделать, при сохранении данных будет создаваться новый объект модели, а не обновляться необходимый.
В качестве аргумента для формы
А для формы
Третьим мы переопределим метод
В теле метода у нас находится
-
-
-
Структура внутри
В переменную
Напомню, что для
В случае с формой
Затем проверяем валидность формы.
Если форма валидна и данные корректны:
Сохраняем форму, тем самым внеся изменения в связанный с ней объект пользователя.
Записываем сообщение об успешном изменении, используя функцию
Возвращаем результат.
В этом моменте происходят различия кода.
При обработке формы изменения данных, для возврата результата мы используем функцию
При обработке формы изменения пароля, для возврата результата мы используем стандартный
Если форма не валидна:
Получаем контекст представления и при помощи метода
1. Когда клиентский запрос поступает на представление, Django вызывает метод `dispatch()` этого представления.
2. `dispatch()` анализирует метод HTTP запроса (GET, POST, PUT, DELETE и т. д.), который пришел от клиента.
3. В зависимости от метода запроса, `dispatch()
вызывает соответствующий метод класса представления. Например, если это GET-запрос, `dispatch()` вызовет метод `get(), если это POST-запрос - метод `post()`, и так далее.4. После обработки запроса соответствующим методом, `dispatch()` возвращает HTTP-ответ.
В нашем методе, мы проверяем, является ли пользователь переданный в адресной строке текущим авторизованным пользователем.
Если является - вызываем метод
dispatch() из родительского класса, в противном случае возвращаем 403 Forbidden.Вторым переопределённым методом будет
get_context_data. С ним мы уже сталкивались ранее и он вполне должен быть знаком, но и тут есть нюансы.В этом методе мы передаём две формы и т.к. у нас формы моделей, нам при их сохранении в переменную, в качестве аргумента необходимо передать объект модели, с которым будет работать форма. Если этого не сделать, при сохранении данных будет создаваться новый объект модели, а не обновляться необходимый.
В качестве аргумента для формы
UserInfoForm мы передаём ключевой аргумент instance с объектом пользователя.А для формы
UserPasswordForm, мы передаём объект пользователя в качестве позиционного аргумента.Третьим мы переопределим метод
post. Он достаточно большой и с первого взгляда можно запутаться, но всё достаточно тривиально.В теле метода у нас находится
if-elif-else конструкция. -
if проверяет отправку формы с изменением данных.-
elif проверяет отправку формы изменения пароля.-
else возвращает эту же страницу без изменений.Структура внутри
if и elif в целом одинаковая, различается только действие в случае успеха.В переменную
form помещаем нашу форму, передав в неё объект пользователя и данные отправленные с формы на сайте. Напомню, что для
UserInfoForm, объект пользователя передаётся как ключевой аргумент instance, т.е. он будет вторым аргументом, а данные формы как позиционный, т.е. первым.В случае с формой
UserPasswordForm, оба аргумента передаются как позиционные и первым идёт объект пользователя, а вторым данные формы.Затем проверяем валидность формы.
Если форма валидна и данные корректны:
Сохраняем форму, тем самым внеся изменения в связанный с ней объект пользователя.
Записываем сообщение об успешном изменении, используя функцию
messages.Возвращаем результат.
В этом моменте происходят различия кода.
При обработке формы изменения данных, для возврата результата мы используем функцию
redirect, перенаправляющую пользователя на новую страницу. Она нужна, поскольку в адресной строке прописывается имя пользователя и при изменении имени пользователя и вызове стандартного метода get, происходит перенаправление, но путь в адресной строке не меняется, что влечёт за собой ошибки, а при использовании redirect, пользователь переходит на новый URL-адрес, включающий в себя новое имя пользователя.При обработке формы изменения пароля, для возврата результата мы используем стандартный
get.Если форма не валидна:
Получаем контекст представления и при помощи метода
render обновляем страницу, включающую в себя введённые ранее пользователем данные.Код представления:
**Шаблон страницы настроек профиля.**
В директории с шаблонами приложения
В этом файле прописываем две формы: отображение сообщения об успешном изменении и кнопку возврата в профиль.
Обратите внимание на код кнопок отправки формы. В них мы указываем атрибут
class UserSettingsView(LoginRequiredMixin, TemplateView):
template_name = 'user_app/profile_settings_page.html'
def dispatch(self, request, *args, **kwargs):
if request.user == get_object_or_404(User, username=self.kwargs.get('username')):
return super().dispatch(request, *args, **kwargs)
else:
raise HttpResponseForbidden("Вы не имеете доступа к этой странице.")
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['user_info_form'] = forms.UserInfoForm(instance=self.request.user)
context['user_password_form'] = forms.UserPasswordForm(self.request.user)
context['title'] = f'Настройки профиля {self.request.user}'
return context
def post(self, request, *args, **kwargs):
if 'user_info_form' in request.POST:
form = forms.UserInfoForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
messages.success(request, 'Данные успешно изменены.')
return redirect('user_app:user_profile_settings', form.cleaned_data.get('username'))
else:
context = self.get_context_data(**kwargs)
context['user_info_form'] = form
return render(request, self.template_name, context)
elif 'user_password_form' in request.POST:
form = forms.UserPasswordForm(request.user, request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Пароль успешно изменён.')
return self.get(request, *args, **kwargs)
else:
context = self.get_context_data(**kwargs)
context['user_password_form'] = form
return render(request, self.template_name, context)
else:
return self.get(request, *args, **kwargs)
**Шаблон страницы настроек профиля.**
В директории с шаблонами приложения
user_app создадим файл profile_settings_page.html.В этом файле прописываем две формы: отображение сообщения об успешном изменении и кнопку возврата в профиль.
Обратите внимание на код кнопок отправки формы. В них мы указываем атрибут
name. Именно по этому атрибуту мы отслеживаем в представлении то, какая форма была отправлена.Код шаблона:
Страница с постами пользователя.
Представление.
В файле
Пропишем три поля:
-
-
-
Переопределим метод
В переопределённом методе
Код представления:
**Шаблон.**
В директории с шаблонами приложения
В качестве шаблона я использовал код из файла
URL-паттерны страницы настроек и всех постов пользователя.
Откроем файл
Завершение.
Осталось изменить шаблон страницы профиля, описанный в прошлом посте, а именно, исправить код кнопок.
Кнопка все посты:
Кнопка настроек профиля:
{% extends 'blog/base.html' %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<div class="container mt-3">
<div class="row d-flex justify-content-between align-items-center">
<div class="col-lg-10 col-sm-12">
<h2>Настройки профиля {{ user }}</h2>
</div>
<div class="col-lg-2 col-sm-12 text-right">
<a class="btn btn-primary my-btn h-100"
href="{% url 'user_app:user_profile' username=user.username %}">Вернуться в профиль</a>
</div>
</div>
<hr>
<div class="row d-flex justify-content-evenly">
<div class="row text-center">
{% if messages %}
<p class="alert alert-success">
{% for message in messages %}
{{ message }}<br>
{% endfor %}
</p>
{% endif %}
</div>
<div class="col-lg-4 col-sm-12">
<h3 class="mb-3 mt-3">Изменить данные:</h3>
<form method="post">
{% csrf_token %}
{{ user_info_form.as_p }}
<button class="btn btn-primary my-btn mt-2" type="submit" name="user_info_form">Отправить</button>
</form>
</div>
<div class="col-lg-4 col-sm-12">
<h3 class="mb-3 mt-3">Изменить пароль:</h3>
<form method="post">
{% csrf_token %}
{{ user_password_form.as_p }}
<button class="btn btn-primary my-btn mt-2" type="submit" name="user_password_form">Отправить
</button>
</form>
</div>
</div>
</div>
{% endblock %}Страница с постами пользователя.
Представление.
В файле
views.py создадим класс UserPostsView, унаследованный от ListView.Пропишем три поля:
-
template_name - файл шаблона.-
context_object_name - имя переменной в шаблоне-
paginate_by - количество элементов на страницеПереопределим метод
get_queryset. В нём вернём список постов, отфильтрованных по переданному в URL-адресе пользователю.В переопределённом методе
get_context_data, в блоке try-except получим объект пользователя по имени пользователя из URL-адреса и запишем его в контекст.Код представления:
class UserPostsView(ListView):
template_name = 'user_app/user_posts_page.html'
context_object_name = 'posts'
paginate_by = 10
def get_queryset(self):
return PostModel.post_manager.filter(author__username=self.kwargs.get('username'))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
try:
author = get_object_or_404(User, username=self.kwargs.get("username"))
except User.DoesNotExist:
raise Http404("Пользователь не найден")
context['author'] = author
context['title'] = f'Посты пользователя {author}'
return context
**Шаблон.**
В директории с шаблонами приложения
user_app создадим файл user_posts_page.html.В качестве шаблона я использовал код из файла
tag_page.html.URL-паттерны страницы настроек и всех постов пользователя.
Откроем файл
urls.py в директории приложения user_app и добавим следующие строки в список urlpatterns:path('<str:username>/settings/', views.UserSettingsView.as_view(), name='user_profile_settings'),
path('<str:username>/posts/', views.UserPostsView.as_view(), name='user_posts'),Завершение.
Осталось изменить шаблон страницы профиля, описанный в прошлом посте, а именно, исправить код кнопок.
Кнопка все посты:
<a class="btn btn-primary my-btn mb-3"
href="{% url 'user_app:user_posts' username=user_profile.username %}">Все посты {{ user_profile }}
</a>
Кнопка настроек профиля:
<a class="btn btn-primary my-btn me-1"
href="{% url 'user_app:user_profile_settings' username=user_profile.username %}">Настройки профиля
</a>
Готово. За эти два поста, мы реализовали публичный профиль пользователя, страницу настроек и страницу всех постов, используя стандартную модель пользователя Django.
Файлы к посту, можно получить в боте по коду: 828730
Пост на сайте.
Поддержать канал.
Файлы к посту, можно получить в боте по коду: 828730
Пост на сайте.
Поддержать канал.
🔥2👏1
Позавчера было ровно 15 месяцев как началась учёба в GB.
Как же блин быстро летит время.
Очередной пост на Пикабу: Обучение: пятнадцатый месяц
😉Расчехляйте лайкомёты)
Как же блин быстро летит время.
Очередной пост на Пикабу: Обучение: пятнадцатый месяц
😉Расчехляйте лайкомёты)
Пикабу
Обучение: пятнадцатый месяц
Автор: proDream
🔥3
Приветствую.
У меня почему-то Хэллоуин ассоциируется не то с комедией, не то с трэш-хоррорами. И вот в преддверии этого события, у меня для вас забавный фильм.
Фильм на сегодня: Смерть ей к лицу (1992).
Краткий синопсис: Эликсир вечной молодости! Сколько женщин мечтают о нем! О нем мечтали и бродвейская звезда Мэдлин Эштон, и Хелен Шарп, у которой эта коварная Мэдлин отбила жениха Эрнеста Мэнвилла, гениального врача-специалиста по пластическим операциям.
Прошли годы, и изрядно полинявшие и уставшие друг от друга дамочки, обращаются за чудотворным снадобьем к некоей колдунье. Итак, эликсир выпит, кожа посвежела, груди подтянулись, но скоро качество лекарства будет проверено... смертью.
Посмотреть можно тут: https://www.sspoisk.ru/film/1889/
А какие ассоциации у вас вызывает Хэллоуин?
У меня почему-то Хэллоуин ассоциируется не то с комедией, не то с трэш-хоррорами. И вот в преддверии этого события, у меня для вас забавный фильм.
Фильм на сегодня: Смерть ей к лицу (1992).
Краткий синопсис: Эликсир вечной молодости! Сколько женщин мечтают о нем! О нем мечтали и бродвейская звезда Мэдлин Эштон, и Хелен Шарп, у которой эта коварная Мэдлин отбила жениха Эрнеста Мэнвилла, гениального врача-специалиста по пластическим операциям.
Прошли годы, и изрядно полинявшие и уставшие друг от друга дамочки, обращаются за чудотворным снадобьем к некоей колдунье. Итак, эликсир выпит, кожа посвежела, груди подтянулись, но скоро качество лекарства будет проверено... смертью.
Посмотреть можно тут: https://www.sspoisk.ru/film/1889/
А какие ассоциации у вас вызывает Хэллоуин?
👍2