6 спринт финальный проект. Тестирование в Django

Архив проекта:

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

1. В проект добавлены кастомные страницы ошибок:

  • 404 page_not_found
  • 500 server_error
  • 403 permission_denied_view

Написан тест, проверяющий, что страница 404 отдает кастомный шаблон.

2. С помощью sorl-thumbnail выведены иллюстрации к постам:

  • в шаблон главной страницы,
  • в шаблон профайла автора,
  • в шаблон страницы группы,
  • на отдельную страницу поста.

Написаны тесты, которые проверяют:

  • при выводе поста с картинкой изображение передаётся в словаре context
    • на главную страницу,
    • на страницу профайла,
    • на страницу группы,
    • на отдельную страницу поста;
  • при отправке поста с картинкой через форму PostForm создаётся запись в базе данных;

3. Создана система комментариев

Написана система комментирования записей. На странице поста под текстом записи выводится форма для отправки комментария, а ниже — список комментариев. Комментировать могут только авторизованные пользователи. Работоспособность модуля протестирована.

4. Кеширование главной страницы

Список постов на главной странице сайта хранится в кэше и обновляется раз в 20 секунд.

5. Тестирование кэша

Написан тест для проверки кеширования главной страницы. Логика теста: при удалении записи из базы, она остаётся в response.content главной страницы до тех пор, пока кэш не будет очищен принудительно.

Финальное задание спринта

Осталось добавить в проект систему подписки на авторов и создать ленту их постов.Задача вам знакома: создайте модель, напишите view-функцию, добавьте в urls.py новые пути, подготовьте шаблоны.

Модель Follow должна иметь такие поля:

  • user — ссылка на объект пользователя, который подписывается. Укажите имя связи: related_name='follower'
  • author — ссылка на объект пользователя, на которого подписываются, имя связи пусть будет related_name='following'

Напишите view-функцию страницы, куда будут выведены посты авторов, на которых подписан текущий пользователь.Ещё две view-функции нужны для подписки на интересного автора и для того, чтобы отписаться от надоевшего графомана:

# posts/views.py

@login_required
def follow_index(request):
    # информация о текущем пользователе доступна в переменной request.user
    # ...
    context = {}
    return render(request, 'posts/follow.html', context)

@login_required
def profile_follow(request, username):
    # Подписаться на автора
    ...

@login_required
def profile_unfollow(request, username):
    # Дизлайк, отписка
    ...
 

Добавьте необходимые адреса в posts/urls.py:

# posts/urls.py
urlpatterns = [
    # ...
    path('follow/', views.follow_index, name='follow_index'),    
    path(
        'profile/<str:username>/follow/',
        views.profile_follow, 
        name='profile_follow'
    ),
    path(
        'profile/<str:username>/unfollow/',
        views.profile_unfollow,
        name="profile_unfollow"
    ),
]
 

Теперь шаблоны.

Создайте шаблон posts/follow.html, куда будут выводиться посты авторов, на которых подписан текущий пользователь. За образец можно взять шаблон posts/index.html, только замените заголовок.

Добавьте в шаблоны index.html и follow.html виджет переключения лент switcher.html:

<!-- templates/posts/includes/switcher.html -->

{% if user.is_authenticated %}
  <div class="row my-3">
    <ul class="nav nav-tabs">
      <li class="nav-item">
        <a 
          class="nav-link {% if index %}active{% endif %}"
          href="{% url 'posts:index' %}"
        >
          Все авторы
        </a>
      </li>
      <li class="nav-item">
        <a 
           class="nav-link {% if follow %}active{% endif %}"
           href="{% url 'posts:follow_index' %}"
        >
          Избранные авторы
        </a>
      </li>
    </ul>
  </div>
{% endif %}
 

Шаблон index.html:

<!-- templates/posts/index.html -->
{% extends 'base.html' %}
{% block title %}Последние обновления на сайте{% endblock %}
{% block content %}
  {% include 'posts/includes/switcher.html' %}
  {% for post in page_obj %}  
    {% if post.group %}   
      <a href="{% url 'posts:group_list' post.group.slug %}">
        все записи группы
      </a>
    {% endif %}
    {% if not forloop.last %}<hr>{% endif %}
  {% endfor %}
  {% include 'posts/includes/paginator.html' %}
{% endblock %}
 

На странице профайла в шапку профиля добавьте ссылку «Подписаться»:

<!-- templates/posts/profile.html -->

<div class="mb-5">
  <h1>Все посты пользователя {{ author.get_full_name }}</h1>
  <h3>Всего постов: {{ posts_count }}</h3>
  {% if following %}
    <a
      class="btn btn-lg btn-light"
      href="{% url 'posts:profile_unfollow' author.username %}" role="button"
    >
      Отписаться
    </a>
  {% else %}
      <a
        class="btn btn-lg btn-primary"
        href="{% url 'posts:profile_follow' author.username %}" role="button"
      >
        Подписаться
      </a>
   {% endif %}
</div>
 

Обратите внимание, добавлен <div class="mb-5"> который сделаем внешний отступ снизу от шапки профиля. В шаблоне используется булева переменная following. Во view-функцию добавьте проверку: подписан ли текущий пользователь на автора, страницу которого он просматривает; присвойте результат проверки переменной following и передайте её в в словаре контекста view-функции profile().

Тестирование

Напишите тесты, проверяющие работу нового сервиса:

  • Авторизованный пользователь может подписываться на других пользователей и удалять их из подписок.
  • Новая запись пользователя появляется в ленте тех, кто на него подписан и не появляется в ленте тех, кто не подписан.


Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: