Share This
Связаться со мной
Крути в низ
Categories
//🐍🚀 Django с нуля. Часть 3: создание профилей, сжатие изображений, CRUD и пагинация

🐍🚀 Django с нуля. Часть 3: создание профилей, сжатие изображений, CRUD и пагинация

В заключительной части туториала разберемся с автоматическим созданием профилей и уменьшением аватарок, реализуем CRUD, импортируем контент из json-файла и сделаем пагинацию.

django s nulja chast 3 sozdanie profilej szhatie izobrazhenij crud i paginacija 5d46c3c - 🐍🚀 Django с нуля. Часть 3: создание профилей, сжатие изображений, CRUD и пагинация

Первая часть 🐍🚀 Django с нуля. Часть 1: пишем многопользовательский блог для клуба любителей задач Python Вторая часть 🐍🚀 Django с нуля. Часть 2: регистрация, авторизация, ограничение доступа

Третий этап разработки

На этом этапе мы займемся профилями пользователей и предоставим авторам возможность добавлять, редактировать и удалять свои записи со стороны фронтенда. Код для всех файлов этой части проекта находится здесь.

Сохранение изображений профилей

На предыдущем этапе мы уже создали модель для профиля и зарегистрировали ее. Теперь нужно обеспечить сохранение аватарок в нужной папке. По умолчанию Джанго создает папку profile_pics (для хранения аватарок) на одном уровне с папками приложений, что не слишком удобно.

Чтобы изменить расположение папки, откройте my_sitesettings.py и добавьте в начало файла import os, а в конец вставьте:

         MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/'      

Запустите сервер, войдите в панель управления – там уже есть раздел Profiles, причем количество профилей равно 0, хотя мы создали нескольких пользователей. Чуть позже мы рассмотрим, как автоматически создавать профили одновременно с регистрацией аккаунтов, а пока что создадим вручную один профиль для админа с аватаркой, и один профиль для пользователя без аватарки – вернее, у него будет аватарка по умолчанию default.jpg, которую вам нужно будет создать и поместить в папку media (но не внутрь profile_pics, а рядом).

Внесите изменения в шаблон профиля usersprofile.html:

         {% extends "blog/base.html" %} {% load crispy_forms_tags %} {% block content %} 	<div class="content-section">   	<div class="media">     	<img class="rounded-circle account-img" src="{{ user.profile.image.url }}">     	<div class="media-body">       	<h2 class="account-heading">{{ user.username }}</h2>   	    <p class="text-secondary">{{ user.email }}</p>     	</div>   	</div>   	<!-- Здесь будет форма --> 	</div> {% endblock content %}      

Теперь профиль админа выглядит так:

django s nulja chast 3 sozdanie profilej szhatie izobrazhenij crud i paginacija 7d6792b - 🐍🚀 Django с нуля. Часть 3: создание профилей, сжатие изображений, CRUD и пагинация

В профиле админа появилась аватарка

Автоматическое создание профилей

Осталось решить задачу с автоматическим созданием профилей во время регистрации. В Джанго для реализации такой логики существуют сигналы. Создайте файл userssignals.py и сохраните в нем этот код. Эти сигналы нужно импортировать в usersapps.py.

Проверим, как работает автоматическое создание профилей – запустим сервер и создадим новый аккаунт. Все получилось:

django s nulja chast 3 sozdanie profilej szhatie izobrazhenij crud i paginacija 0e11277 - 🐍🚀 Django с нуля. Часть 3: создание профилей, сжатие изображений, CRUD и пагинация

Теперь профили пользователей создаются автоматически Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека питониста» Интересно, перейти к каналу

Заполнение и обновление профилей

Пользователям нужна возможность самостоятельно вносить изменения в профиль – менять фото, ник и емейл, например. Для этого внесем дополнения в файл usersforms.py – добавим импорт from .models import Profile в начало и этот код в конец:

         class UserUpdateForm(forms.ModelForm): 	email = forms.EmailField()   	class Meta:     	model = User     	fields = ['username', 'email']     class ProfileUpdateForm(forms.ModelForm): 	class Meta:     	model = Profile     	fields = ['image']      

Перейдем к usersviews.py – теперь он должен выглядеть так. В шаблон profile.html тоже нужно внести дополнения – вставьте этот код вместо комментария «здесь будет форма»:

            	<form method="POST" enctype="multipart/form-data">       	{% csrf_token %}       	<fieldset class="form-group">           	<legend class="border-bottom mb-4">Ваш профиль</legend>           	{{ u_form|crispy }}               {{ p_form|crispy }}       	</fieldset>       	<div class="form-group">           	<button class="btn btn-outline-info" type="submit">Обновить</button>       	</div>   	</form>     

Теперь пользователи могут изменять информацию в своих профилях:

django s nulja chast 3 sozdanie profilej szhatie izobrazhenij crud i paginacija 18a5a8a - 🐍🚀 Django с нуля. Часть 3: создание профилей, сжатие изображений, CRUD и пагинация

Пользователи могут самостоятельно изменить ник, емейл и аватар

Автоматическое сжатие изображений

Если пользователи будут загружать слишком большие изображения, сервер скоро окажется перегруженным. Поэтому имеет смысл реализовать автоматическое сжатие изображений, используемых в качестве аватарок. Такую возможность предоставляет библиотека Pillow, которую мы уже использовали. Для сжатия фото с помощью Pillow в usersmodels.py нужно сохранить этот код. Теперь крупные изображения уменьшаются автоматически.

Отображение аватарок в постах

Пока что изображения пользователей видны только в их профилях. Чтобы фото авторов отображались в постах блога, внесем дополнения в шаблон bloghome.html – сохраните в нем этот код. Аватарка пользователя теперь показывается в посте:

django s nulja chast 3 sozdanie profilej szhatie izobrazhenij crud i paginacija a01e1ea - 🐍🚀 Django с нуля. Часть 3: создание профилей, сжатие изображений, CRUD и пагинация

Аватарка автора отображается рядом с его записями

CRUD

Чтобы дать возможность пользователям управлять постами, нужно реализовать CRUD – набор операций по созданию, редактированию и удалению контента. Создать такую функциональность будет проще, если перейти от функций представления к классам. Для этого нынешнее содержимое файла blogviews.py нужно изменить на это, а код blogurls.py должен выглядеть так. Обратите внимание на классы PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView) и PostDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView) – они обеспечивают создание, редактирование и удаление записей только зарегистрированными пользователями; при этом редактировать и удалять посты могут лишь их авторы.

Для просмотра отдельных постов создадим шаблон post_detail.html вот с таким кодом. Теперь каждый пост можно открыть отдельно: http://localhost:8000/post/1/. Добавим эту возможность в шаблон home.html:

         <h2><a class="article-title" href="{% url 'post-detail' post.id %}">{{ post.title }}</a></h2>     

Перейдем к шаблону создания новых постов. Создайте файл post_form.html с таким кодом. Форма будет отображаться по адресу http://localhost:8000/post/new/:

django s nulja chast 3 sozdanie profilej szhatie izobrazhenij crud i paginacija 18a2356 - 🐍🚀 Django с нуля. Часть 3: создание профилей, сжатие изображений, CRUD и пагинация

Пользователи могут создавать новые записи

После создания записи следует перенаправить пользователя на отдельную страницу поста. Для этого измените существующий код blogmodels.py на этот, и все заработает:

django s nulja chast 3 sozdanie profilej szhatie izobrazhenij crud i paginacija ca0d068 - 🐍🚀 Django с нуля. Часть 3: создание профилей, сжатие изображений, CRUD и пагинация

Отдельная страница для каждой записи

Записи уже можно обновлять, но пока что нельзя удалять. Создадим нужный шаблон – файл blogpost_confirm_delete.html. Код для него есть здесь. Теперь удаление работает, после подтверждения удаления запись исчезает, а пользователь перенаправляется на главную страницу блога:

django s nulja chast 3 sozdanie profilej szhatie izobrazhenij crud i paginacija f6c09ef - 🐍🚀 Django с нуля. Часть 3: создание профилей, сжатие изображений, CRUD и пагинация

Подтверждение удаления

Осталось добавить ссылку на создание новой записи на панель навигации – мы сделаем это в шаблоне base.html, добавив всего одну строку <a class="nav-item nav-link" href="{% url 'post-create' %}">Новая запись</a>. Все готово! Если что-то не работает, сверьтесь с готовым кодом к третьему этапу.

Четвертый этап разработки

На заключительном этапе работы над проектом мы загрузим контент из json файла (с помощью интерактивной консоли Django), сделаем пагинацию и обеспечим вывод всех постов автора на отдельной странице.

Импорт контента из файла json

Создавать посты от имени нескольких авторов утомительно, поэтому мы воспользуемся загрузкой контента из готового файла posts.json. Запустим интерактивную консоль Джанго python manage.py shell и проведем импорт. Отступы в консоли – 2 вместо обычных 4:

         >>> import json >>> from blog.models import Post >>> with open('posts.json', encoding="utf8") as f: ...   posts_json = json.load(f) ... >>> for post in posts_json: ...   post = Post(title=post['title']), content=post['content'], author_id=post['user_id'] ...   post.save() ... >>> exit()      

Теперь на нашей главной странице отображается множество записей.

Пагинация

Пора реализовать пагинацию – разбиение постов на страницы. Для разделения постов на страницы внесем изменения в класс PostListView(ListView) в файле blogviews.py – добавим строку paginate_by = 5. Отредактируем шаблон home.html – разместим логику пагинатора между {% end for %} и {% end block content%} в конце файла. Записи теперь разделены на страницы:

django s nulja chast 3 sozdanie profilej szhatie izobrazhenij crud i paginacija d914ad5 - 🐍🚀 Django с нуля. Часть 3: создание профилей, сжатие изображений, CRUD и пагинация

Пагинатор разделяет записи по 5 постов на странице

Еще было бы здорово показывать на странице пользователя все записи, которые он создал – с пагинацией, если записей много. Для этого мы добавим в blogviews.py импорт get_object_or_404 и новый класс:

         class UserPostListView(ListView): 	model = Post 	template_name = 'blog/user_posts.html'  # <app>/<model>_<viewtype>.html 	context_object_name = 'posts' 	paginate_by = 5   	def get_queryset(self):     	user = get_object_or_404(User, username=self.kwargs.get('username'))     	return Post.objects.filter(author=user).order_by('-date_posted')      

Сделаем шаблон user_posts.html и добавим новый путь в файле blogurls.py:

         path('user/<str:username>', UserPostListView.as_view(), name='user-posts').     

Осталось внести поправку в данные автора в шаблон home.html:

         <a class="mr-2" href="{% url 'user-posts' post.author.username %}">{{ post.author }}</a>     

и в post_detail.html:

         <a class="mr-2" href="{% url 'user-posts' object.author.username %}">{{ object.author }}</a>.     

И все заработало:

django s nulja chast 3 sozdanie profilej szhatie izobrazhenij crud i paginacija 3aabf3c - 🐍🚀 Django с нуля. Часть 3: создание профилей, сжатие изображений, CRUD и пагинация

Записи пользователя выводятся на его личной странице

Весь код для четвертого этапа можно взять здесь.

Заключение

Поэтапное создание простого веб-приложения дает возможность быстро освоить основные принципы разработки в Django. Фреймворк позволяет достаточно просто реализовать сложную функциональность – например, CRUD, – а соответствующие библиотеки помогают разрабатывать формы и автоматически сжимать изображения. Напоминаем, что код для всех этапов проекта доступен здесь.

***

Материалы по теме

  • Django Junior: путь продолжающего
  • Безопасная загрузка изображений в веб-приложении на Django
  • Самый полный видеокурс по Django от установки до проекта

  • 9 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Свежие комментарии

    Рубрики

    About Author 01.

    blank
    Roman Spiridonov

    Моя специальность - Back-end Developer, Software Engineer Python. Мне 39 лет, я работаю в области информационных технологий более 5 лет. Опыт программирования на Python более 3 лет. На Django более 2 лет.

    Categories 05.

    © Speccy 2022 / All rights reserved

    Связаться со мной
    Close