Share This
Связаться со мной
Крути в низ
Categories
//Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

Разрабатываем портал, на котором каждый рекрутер сможет найти своего разработчика :). Система поиска позволяет подобрать нужного специалиста по резюме, портфолио или описанию проектов; рейтинг проекта поможет оценить квалификацию, а мессенджер – послать оффер.

pishem rekrutingovyj portal na django chast 1 veb prilozhenie na django 7dd5d6c - Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

Это достаточно сложный проект, состоящий из двух взаимосвязанных приложений – Projects и Users. Разработчики могут создавать профили и добавлять в портфолио проекты. Предусмотрены поиск, оценка проектов и обмен сообщениями. Реализована фильтрация по тегам (для проектов) и по скиллам (для профилей). Весь код проекта ITfinder находится здесь.

Обзор проекта

Сайт включает:

  1. Систему аутентификации и авторизации.
  2. Поиск по профилям, навыкам, тегам, описаниям проектов.
  3. Фильтрацию по тегам и скиллам.
  4. CRUD операции для создания, редактирования, удаления профилей, проектов, тегов и скиллов.
  5. Мессенджер.
  6. Систему оценок и отзывов о проектах.

pishem rekrutingovyj portal na django chast 1 veb prilozhenie na django 873e36c - Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

Главная страница – профили разработчиков

pishem rekrutingovyj portal na django chast 1 veb prilozhenie na django d22c8f5 - Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

Раздел “Проекты”

pishem rekrutingovyj portal na django chast 1 veb prilozhenie na django 6fcc56d - Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

Профиль разработчика

pishem rekrutingovyj portal na django chast 1 veb prilozhenie na django 753af32 - Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

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

Первый этап

Работа над Django проектом начинается с установки зависимостей, создания базовой структуры проекта и входящих в него приложений.

Установка Django и создание структуры проекта

Выполним установку фреймворка и зависимостей с помощью встроенного менеджера виртуального окружения venv:

         python -m venv itfindervenv cd itfinder venvscriptsactivate pip install -r requirements.txt      

Создадим новый проект под названием itfinder:

         django-admin startproject itfinder     

Проект состоит из двух приложений – «Проекты» и «Пользователи». Начнем работу с создания скелета проекта projects:

         cd itfinder python manage.py startapp projects      

Django автоматически создает базовую структуру приложения, но зарегистрировать projects в конфигурационном файле проекта придется вручную. Откройте файл itfindersettings.py, и добавьте в список INSTALLED_APPS строку 'projects.apps.ProjectsConfig'.

Теперь нужно создать основные маршруты приложения «Проекты». Создайте файл projects/urls.py и сохраните в нем нужные маршруты:

         from django.urls import path from . import views urlpatterns = [     path('', views.projects, name="projects"),     path('project-object/<str:pk>/', views.project, name="project"), ]      

Чтобы маршруты projects были доступны на уровне проекта, нужно включить их в глобальные URL – в файле itfinderurls.py:

         from django.contrib import admin from django.urls import path, include   urlpatterns = [      path('admin/', admin.site.urls),      path('', include('projects.urls')), ]      

Шаблоны приложения Projects

Создайте папку templates внутри projects, и в ней два файла – projects.html и single-project.html. Тестовый код для шаблона projects.html:

         <!DOCTYPE html> <html> <head>    <title>Шаблон для вывода проектов</title> </head> <body> <h2>Здесь будут все проекты</h2> {% for project in projects %} <p>Номер проекта: #{{ project.id }}</p> <h3>Название проекта: <a href="{% url 'project' project.id %}">{{ project.title }}</a></h3> <em>{{ project.description }}</em> {% endfor %} </body> </html>      

Для single-projects.html:

         <!DOCTYPE html> <html> <head>     <title>Шаблон для отдельного проекта</title> </head> <body> <h1>Подробная информация о проекте</h1> <h3>Проект #{{ project.id }}</h3> <p>{{ project.title }}</p> <br> <em>{{ project.description }}</em> </body> </html>      

Добавим import os и ссылку на шаблоны в файл настроек itfinder/settings.py:

          'DIRS': [os.path.join(BASE_DIR, 'templates')],     

Принцип работы Django основан на схеме MVT – (Модель, Представление, Шаблон). Если вам не приходилось раньше работать с Джанго, схему работы фреймворка может прояснить приведенный ниже пример того, как функция представления передает данные в шаблон, который мы только что создали. Напишем тестовые функции представления в файле projects/views.py:

         from django.shortcuts import render def projects(request):     projectsList = [{'id':'1',     'title':'Онлайн-кинотеатр',     'description':'Кинотеатр с самой полной библиотекой фильмов.'},     {'id':'2',     'title':'Платформа с ИТ-курсами',     'description':'Курсы по фронтенду, бэкенду и мобильной разработке.'},     {'id':'3',     'title':'Рекрутинговый портал',      'description':'Вакансии для специалистов экстра-класса.'},       ]     return render(request, 'projects/projects.html', {'projects':projectsList}) def project(request):     return render(request, 'projects/single-project.html')      

Запустите сервер python manage.py runserver и откройте адреса http://localhost:8000/ и http://localhost:8000/project/ – все работает, функция передает в шаблон тестовые данные:

pishem rekrutingovyj portal na django chast 1 veb prilozhenie na django 2b43ad7 - Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

Тестовое представление проектов

В реальных приложениях модели извлекают информацию из базы данных, а представления могут быть основаны не на функциях, а на классах.

База данных

Джанго по умолчанию работает с базой типа SQLite3 – настройки для подключения указаны в файле itfinder/settings.py. Для инициализации базы данных выполним команду python manage.py migrate. Эта же команда используется для применения изменений, в дальнейшем мы будем ею пользоваться неоднократно, но уже в другом формате – после команды python manage.py makemigrations, которая отслеживает все изменения в моделях.

После инициализации базы Джанго открывает доступ к панели администрирования – http://localhost:8000/admin. Однако для создания учетной записи администратора (суперпользователя) нужно выполнить еще одну команду:

         python manage.py createsuperuser     

В ходе создания аккаунта можно пропустить введение имени – тогда по умолчанию будет назначен юзернейм user, и емейла (поле останется пустым). Если сейчас войти в панель администрирования, можно отметить, что пока там можно создавать, изменять и удалять только новых пользователей и группы.

pishem rekrutingovyj portal na django chast 1 veb prilozhenie na django 2f76178 - Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

Админ-панель

Для создания, редактирования и удаления других типов записей (профилей, проектов, комментариев) нужно сначала определить, а затем зарегистрировать в админ-панели нужные модели. Все атрибуты таблиц базы данных и взаимоотношения между ними определяются в файлах типа models.py. Модели представляют собой классы, все атрибуты которых ORM слой Django связывает с соответствующими полями таблиц. Благодаря этому отпадает необходимость использовать язык SQL.

Создадим нашу первую модель, которая будет хранить данные обо всех проектах, добавленных в раздел «Проекты». Это первый вариант модели, в дальнейшем мы ее расширим и дополним:

         from django.db import models import uuid class Project(models.Model):     title = models.CharField(max_length=100)     slug = models.SlugField()     description = models.TextField(null=True, blank=True)     demo_link = models.CharField(max_length=500, null=True, blank=True)     source_link = models.CharField(max_length=500, null=True, blank=True)     created = models.DateTimeField(auto_now_add=True)     id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)     def __str__(self):         return self.title      

После создания модели нужно подготовить миграции:

         python manage.py makemigrations     

И применить их к базе:

         python manage.py migrate     

Чтобы модель была доступна в панели администрирования, ее нужно зарегистрировать в файле itfinder/admin.py:

         from django.contrib import admin from .models import Project   admin.site.register(Project)      

После регистрации форма добавления проектов становится доступной в панели администрирования:

pishem rekrutingovyj portal na django chast 1 veb prilozhenie na django 285562d - Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

Теперь можно добавлять проекты

В нашем приложении будет несколько моделей, связанных друг с другом различными способами:

  1. Один к одному – у одного пользователя может быть только один профиль.
  2. Один ко многим – один пользователь (профиль) может быть автором множества проектов; один проект может получить множество отзывов / комментариев / оценок. Для реализации такой связи служит ForeignKey. Установление связи между таблицами с помощью ForeignKey нуждается в дополнительных параметрах на случай удаления одной из таблиц. В случае с проектом и отзывами к нему это CASCADE – он удаляет отзыв в случае удаления проекта, к которому отзыв относился.
  3. Многие ко многим – у одного проекта может быть множество тегов, а у пользователя – несколько навыков. Один и тот же тег (навык) может использоваться во множестве проектов (или профилей).

Связь проекта с тегами и отзывами

Расширим модель Project, добавив в нее связь с таблицами тегов и отзывов:

         from django.db import models import uuid  class Tag(models.Model):     name = models.CharField(max_length=100)     slug = models.SlugField()     created = models.DateTimeField(auto_now_add=True)     id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)       def __str__(self):         return self.name	    class Project(models.Model):      title = models.CharField(max_length=100)      slug = models.SlugField()      description = models.TextField(null=True, blank=True)      tags = models.ManyToManyField(Tag, blank=True)      total_votes = models.IntegerField(default=0, null=True, blank=True)      votes_ratio = models.IntegerField(default=0, null=True, blank=True)      demo_link = models.CharField(max_length=500, null=True, blank=True)      source_link = models.CharField(max_length=500, null=True, blank=True)      created = models.DateTimeField(auto_now_add=True)      id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)        def __str__(self):          return self.title   class Review(models.Model):      project = models.ForeignKey(Project, on_delete=models.CASCADE)      VOTE_TYPE = (      ('up', 'Up Vote'),      ('down', 'Down Vote'),      )      review_text = models.TextField(null=True, blank=True)      value = models.CharField(max_length=200, choices=VOTE_TYPE)      created = models.DateTimeField(auto_now_add=True)      id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)	        def __str__(self):          return self.value      

Зарегистрируем новые модели в admin.py:

         from django.contrib import admin from .models import Project, Review, Tag   admin.site.register(Project) admin.site.register(Review) admin.site.register(Tag)      

Выполним миграции и откроем админ-панель – теперь к проектам можно добавлять теги, рейтинг и отзывы:

pishem rekrutingovyj portal na django chast 1 veb prilozhenie na django e93da7c - Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

Теги, рейтинг и отзывы о проектах

Создайте несколько проектов или воспользуйтесь готовой базой данных. Эта информация нам понадобится для реализации следующего шага – запросов.

Запросы к базе данных

Структура запроса к базе данных в Джанго выглядит так:

         Queryset = ModelName.objects.all()     
  • где Queryset – переменная, которой передаются результаты запроса;
  • ModelName – название модели;
  • objects – атрибут объекта модели;
  • all() – метод.

Кроме all(), который возвращает все объекты модели, есть множество других методов, например:

  • filter, filter_by – фильтруют по значениям атрибутов. При этом значение может быть равно запросу, содержать ключевое слово или начинаться с определенного критерия. Фильтры могут учитывать или игнорировать регистр.
  • icontains – проверяет, содержит ли поле определенный запрос.
  • get – возвращает единичный объект;
  • exclude – исключает определенные значения.

Тестировать запросы удобно в интерактивной консоли, которую запускают командой python manage.py shell:

         python manage.py shell >>> from projects.models import Project >>> projects = Project.objects.all() >>> print(projects) <QuerySet [<Project: EverGreen - магазин люксовой эко-косметики>, <Project: ITGi gs - платформа для поиска ИТ-фрилансеров>, <Project: BlahBlahChat - социальная с еть нового поколения>, <Project: RoboShop - магазин электронных игрушек>, <Proje ct: SuperCook - сайт для кулинарного блогера>]> >>> singleproject = Project.objects.get(title='RoboShop - магазин электронных иг рушек') >>> print(singleproject) RoboShop - магазин электронных игрушек >>> print(singleproject.created) 2022-07-05 15:40:34.240616+00:00 >>> print(singleproject.slug) roboshop-magazin-igrushek >>> exit()      

Передача данных из базы в шаблон

Откройте файл itfinder/views.py, добавьте в него импорт моделей:

         from .models import Project     

И измените функцию представления projects на эту:

         def projects(request):     projects = Project.objects.all()     context = {'projects': projects}     return render(request, 'projects/projects.html', context)     

Функция представления отдельного проекта теперь должна выглядеть так:

         def project(request, pk):     projectObj = Project.objects.get(id=pk)     tags = projectObj.tags.all()     return render(request, 'projects/single-project.html', {'project': projectObj})     

В шаблон для вывода отдельных проектов нужно добавить отображение тегов:

         <!DOCTYPE html> <html> <head>             	<title>Шаблон для отдельного проекта</title>             	<meta charset="UTF-8"> </head> <body> <h1>Подробная информация о проекте</h1> <h3>Проект {{ project.id }}</h3> <p>{{ project.title }}</p> <br> <ul> {% for tag in project.tags.all %} <li>{{ tag }}</li> {% endfor %} </ul> <em>{{ project.description }}</em> </body> </html>      

Запустите сервер – на главной странице сайта появилось описание проектов из базы данных:

pishem rekrutingovyj portal na django chast 1 veb prilozhenie na django 2ccd4e3 - Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

Вывод всех проектов

И описание отдельного проекта тоже выводится – с тегами:

pishem rekrutingovyj portal na django chast 1 veb prilozhenie na django 98d68e5 - Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

Вывод отдельного проекта

Код и база данных для первого этапа – здесь.

Второй этап

Начнем с разработки CRUD – функциональности для создания, редактирования и удаления проектов.

Сначала сделаем шаблон для формы, которая будет использоваться как для создания, так и для редактирования проектов. Сохраните этот код в project_form.html:

         {% block content %} <h1>Информация о проекте</h1> <form method="POST">     {% csrf_token %}     {{ form.as_p }}     <input type="submit" name="" value="Добавить проект"> </form> {% endblock content %}     

Токен csrf_token обеспечивает защиту сайта от атак; кроме того, без него форма просто не будет обрабатываться. Параметр .as_p создает теги <p></p> вокруг элементов формы.

Создайте файл itfinderforms.py:

         from django.forms import ModelForm from .models import Project   class ProjectForm(ModelForm):     class Meta:         model = Project         fields = ['title', 'slug', 'tags', 'description', 'demo_link', 'source_link']      

Во многих случаях вместо строки с перечислением полей можно указать fields = '__all__' – тогда модуль ModelForm автоматически сгенерирует форму на основе модели проекта, и перечислять поля по отдельности не придется. При этом модуль проигнорирует поля, которые не подлежат редактированию (как уникальный UUID), и пропустит поля, создаваемые во время сохранения записи (как created). Однако в нашей модели Project есть поля, которые обновляются при подсчете рейтинга, и пользователи не должны иметь доступа к ним, поэтому в форме мы перечисляем только редактируемые поля.

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

         <strong><a href="{% url 'create-project' %}">Добавить проект</a></strong>     

Перезагрузите страницу – форма создания нового проекта благополучно загружается, хотя пока что не имеет никакого дизайна (и ничего не сохраняет):

pishem rekrutingovyj portal na django chast 1 veb prilozhenie na django cd03471 - Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

Форма без дизайна

Чтобы форма сохраняла данные, внесем дополнения в itfinder/views.py добавим импорт redirect и обработку POST:

         def createProject(request):     form = ProjectForm()     if request.method == 'POST':         form = ProjectForm(request.POST)         if form.is_valid():             form.save()     return redirect('projects')      

Теперь данные сохраняются – запись добавлена в список проектов. Реализовать редактирование проектов несложно. Сначала добавим новую функцию в views.py:

         def updateProject(request, pk):     project = Project.objects.get(id=pk)     form = ProjectForm(instance=project)     if request.method == 'POST':         form = ProjectForm(request.POST, instance=project)         if form.is_valid():             form.save()             return redirect('projects')     context = {'form': form}     return render(request, 'projects/project_form.html', context)      

Параметр instance=project здесь обеспечивает предзаполнение формы существующими в базе данными:

pishem rekrutingovyj portal na django chast 1 veb prilozhenie na django f0c391d - Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

Автоматическое заполнение существующими данными

Теперь сделаем нужный маршрут в urls.py:

         path('update-project/<str:pk>', views.updateProject, name="update-project"),     

И добавим ссылку на редактирование в шаблон projects.html:

         <h4><a href="{% url 'update-project' project.id %}">Редактировать проект</a></h4>     

Для удаления проектов (а в дальнейшем – и других объектов) нужно сделать шаблон, запрашивающий подтверждение действий пользователя. Создайте файл delete.html и сохраните в нем код:

         {% block content %} <form action="" method="POST">      {% csrf_token %}      <p>Вы действительно хотите удалить "{{ object }}"?</p>      <a href="{% url 'projects' %}">Отмена</a>      <input type="submit" name="" value="Подтвердить удаление" /> </form> {% endblock %}      

В файл views.py добавьте функцию удаления:

         def deleteProject(request, pk):     project = Project.objects.get(id=pk)     if request.method == 'POST':         project.delete()         return redirect('projects')     context = {'object': project}     return render(request, 'projects/delete.html', context)     

На этом работа по созданию CRUD закончена, перейдем к дизайну и статическим файлам.

Статические файлы

Создайте папку static в корневой директории проекта. Внутри static создайте 3 папки:

  • styles – в ней будут находиться css файлы. Поместите туда main.css.
  • js – для скриптов. Положите туда этот скрипт.
  • uikit – для стилей фронтенда. Там должны быть все эти файлы.

Чтобы Джанго знал, откуда загружать стили, нужно внести дополнения в файл настроек settings.py:

         STATICFILES_DIRS = [ 	BASE_DIR / 'static' ]      

Помимо шаблонов, находящихся в папке projects, нам понадобится набор шаблонов, определяющих внешний вид проекта на, так сказать, глобальном уровне. Для этих шаблонов нужно создать папку templates в корневой директории проекта itfinder. Сейчас в эту папку нужно поместить эти два файла – base.html и navbar.html, позже мы добавим туда еще несколько шаблонов.

Шаблоны в папке templates/projects нужно заменить на эти – они соответствуют готовой версии приложения и содержат ссылки на атрибуты моделей, которые мы разработаем на последующих этапах.

Последнее, что мы сделаем на этом этапе – добавим фильтр проектов по тегам. Для этого в views.py нужно добавить эту функцию:

         def projects_by_tag(request, tag_slug):     tag = get_object_or_404(Tag, slug=tag_slug)     projects = Project.objects.filter(tags__in=[tag])     context = {     	"projects": projects 	}       return render(request, "projects/projects.html", context)      

В файл urls.py надо вставить маршрут:

         path('tag/<slug:tag_slug>', views.projects_by_tag, name="tag"),     

В шаблон projects.html добавить этот код:

         <div class="project__tags">    {% for tag in project.tags.all %}       <a href="{% url 'tag' tag.slug %}" class="tag tag--pill tag--main">{{tag}}</a>    {% endfor %} </div>      

А в шаблон single-project.html этот:

         <div class="singleProject__toolStack">   {% for tag in project.tags.all %}       <a href="{% url 'tag' tag.slug %}" class="tag tag--pill tag--sub tag--lg">{{tag}}</a>   {% endfor %}           	 </div>     

Запустим сервер – наш проект получил дизайн и обзавелся фильтрацией по тегам, причем фильтр работает как на главной странице, так и на странице отдельного проекта:

pishem rekrutingovyj portal na django chast 1 veb prilozhenie na django 5b0a805 - Пишем рекрутинговый портал на Django: часть 1. Веб-приложение на Django

Фильтр по тегу Angular

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

В следующей части мы реализуем добавление изображений для проектов с фронтенда, а также разработаем основную функциональность второго приложения, Users.

***

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

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

  • 0 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