🐍🚀 Создаем рекрутинговый портал на Django: часть 3

В заключительной части: создание мессенджера, реализация поиска по профилям и проектам, отзывы и пагинация.
🐍🚀 Создаем рекрутинговый портал на Django: часть 3

Пятый этап

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

Мессенджер

Начнем работу с создания модели Message – сохраните этот код в users/models.py:

        class Message(models.Model):
    sender = models.ForeignKey(
        Profile, on_delete=models.SET_NULL, null=True, blank=True)
    recipient = models.ForeignKey(
        Profile, on_delete=models.SET_NULL, null=True, blank=True, related_name="messages")
    name = models.CharField(max_length=200, null=True, blank=True)
    email = models.EmailField(max_length=200, null=True, blank=True)
    subject = models.CharField(max_length=200, null=True, blank=True)
    body = models.TextField()
    is_read = models.BooleanField(default=False, null=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.subject
 
    class Meta:
        ordering = ['is_read', '-created']

    

Подготовьте и примените миграции:

        python manage.py makemigrations
python manage.py migrate 

    

После этого добавьте импорт Message и новый класс в users/form.py:

        class MessageForm(ModelForm):
    class Meta:
        model = Message
        fields = ['name', 'email', 'subject', 'body']
 
    def __init__(self, *args, **kwargs):
        super(MessageForm, self).__init__(*args, **kwargs)
 
        for name, field in self.fields.items():
            field.widget.attrs.update({'class': 'input'})

    

Шаблоны, которые понадобятся для мессенджера:

Сохраните эти шаблоны в templates/users. Еще мы добавим ссылку на входящие в шаблоне navbar.html{% url 'inbox' %}.

Мессенджер на Django
Мессенджер на Django
Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека питониста»

Отзывы о проектах

В первой части туториала мы уже частично реализовали функциональность для отзывов о проектах. Теперь нам нужно связать отзывы с пользователями. Для этого мы внесем дополнения в модель Project:

            @property
    def reviewers(self):
        queryset = self.review_set.all().values_list('owner__id', flat=True)
        return queryset
 
    @property
    def getVoteCount(self):
        reviews = self.review_set.all()
        upVotes = reviews.filter(value='up').count()
        totalVotes = reviews.count()
 
        ratio = (upVotes / totalVotes) * 100
        self.vote_total = totalVotes
        self.vote_ratio = ratio
 
        self.save()
    

Дополним класс Review:

        class Review(models.Model):
    VOTE_TYPE = (
        ('up', 'Положительная оценка'),
        ('down', 'Отрицательная оценка'),
    )
    owner = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True)
    project = models.ForeignKey(Project, on_delete=models.CASCADE)
    body = 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)
 
    class Meta:
        unique_together = [['owner', 'project']]
 
    def __str__(self):
        return self.value

    

В шаблоне single-projects.html изменим ссылки на авторов отзывов: {% url 'user-profile' review.owner %}, после чего добавим форму отзыва в projects/forms.py:

        class ReviewForm(ModelForm):
    class Meta:
        model = Review
        fields = ['value', 'body']
 
        labels = {
            'value': 'Оцените проект',
            'body': 'Добавьте комментарий'
        }
 
    def __init__(self, *args, **kwargs):
        super(ReviewForm, self).__init__(*args, **kwargs)
 
        for name, field in self.fields.items():
            field.widget.attrs.update({'class': 'input'})


    

Осталось внести небольшие изменения в представление проекта в файле projects/views.py. Добавим import ReviewForm и код:

        def project(request, project_slug):
   project = Project.objects.get(slug=project_slug)
   tags = project.tags.all()
   form = ReviewForm()
   if request.method == 'POST':
       form = ReviewForm(request.POST)
       review = form.save(commit=False)
       review.project = project
       review.owner = request.user.profile
       review.save()
       project.getVoteCount
       messages.success(request, 'Ваш отзыв был добавлен!')
       return redirect('project', project_slug=project.slug)   
   return render(request, 'projects/single-project.html', {'project': project, 'form': form})


    

Готово, теперь на сайте есть система отзывов:

Система комментариев на Django
Система комментариев на Django

Шестой этап

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

Пагинация

Сначала сделаем пагинацию для вывода проектов. Создайте файл projects/utils.py, а в файл projects/views.py добавьте импорт:

        from django.core import paginator
from .utils import paginateProjects

    

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

        {% include 'pagination.html' with queryset=projects custom_range=custom_range %}
    

После этого в папку с глобальными шаблонами положите файл pagination.html.

Запустите сервер и проверьте: проекты теперь выводятся постранично.

Таким же образом сделаем пагинацию для постраничного вывода профилей в приложении Users:

Готово – теперь профили выводятся по 6 штук на странице:

Пагинация
Пагинация

Поиск

Мы реализуем поиск по проектам и профилям с помощью модуля Q. Сначала добавим импорт from django.db.models import Q и эту функцию в projects/utils.py:

         def searchProjects(request):
     search_query = ''
     if request.GET.get('search_query'):
        search_query = request.GET.get('search_query')
     tags = Tag.objects.filter(name__icontains=search_query)
 
    projects = Project.objects.distinct().filter(
        Q(title__icontains=search_query) |
        Q(description__icontains=search_query) |
        Q(owner__name__icontains=search_query) |
        Q(tags__in=tags)
    )
    return projects, search_query
    

Использование модуля Q значительно изменит представление для вывода проектов:

        def projects(request):
    projects, search_query = searchProjects(request)
    custom_range, projects = paginateProjects(request, projects, 6)
 
    context = {'projects': projects,
            'search_query': search_query, 'custom_range': custom_range}
    return render(request, 'projects/projects.html', context)


    

Вызов Q в шаблоне projects.html производит {{ search_query }}. Все готово – поиск по проектам работает:

Результаты поиска по запросу "магазин"
Результаты поиска по запросу "магазин"

То же самое сделаем для поиска по профилям. Добавим функцию поиска в users/utils.py:

        def searchProfiles(request):
    search_query = ''
    if request.GET.get('search_query'):
        search_query = request.GET.get('search_query')
 
    skills = Skill.objects.filter(name__icontains=search_query)
    profiles = Profile.objects.distinct().filter(
        Q(name__icontains=search_query) |
        Q(short_intro__icontains=search_query) |
        Q(skill__in=skills)
    )
    return profiles, search_query
    

Изменим представление для вывода профилей в users/views.py:

        def profiles(request):
    profiles, search_query = searchProfiles(request)
 
    custom_range, profiles = paginateProfiles(request, profiles, 6)
    context = {'profiles': profiles, 'search_query': search_query,
            'custom_range': custom_range}
    return render(request, 'users/profiles.html', context)


    

И добавим {{ search_query }} в profiles.html. Готово – поиск по профилям работает:

Результаты поиска по запросу "Python"
Результаты поиска по запросу "Python"

На этом разработка сайта завершена. Код готового проекта можно взять в репозитории ITfinder.

***

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


Комментарии

 
 

ВАКАНСИИ

Добавить вакансию
Senior Software Engineer (Java)
от 4500 USD до 6000 USD
Senior DevOps Developer
Лимасол, по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

Подпишись

на push-уведомления