Giter Site home page Giter Site logo

prrromanssss / intensiveyandex-backend Goto Github PK

View Code? Open in Web Editor NEW
0.0 0.0 0.0 8.04 MB

This project is a repository for Django intensive homework from the Yandex Academy

Python 63.50% HTML 24.37% CSS 1.56% JavaScript 10.57%
bootstrap django-project python-3 sqlite3 yandex

intensiveyandex-backend's Introduction

Hi there, I'm Prrromanssss!

Gopher coding

Talking about personal stuffs:

  • 🔭 Go backend developer
  • 🌱 I’m currently learning all sorts of backend tools
  • 💬 Ask me about the work of Hermann Hesse
  • 📫 How to reach me:
  • ⚡ Fun fact: I'm still thinking about it
  • 😅 I have a lot of python code, but I'm real gopher 😏 (I love goroutines)

Statistics:

Top Langs

Languages:

Go  Python  C  Scheme  Java  C++ 

Backend tools:

PostgreSQL  Redis  Apachekafka  RabbitMQ  Docker  Kubernetes  gRPS  Ubuntu  Git 

intensiveyandex-backend's People

Contributors

prrromanssss avatar sus4no avatar twowscreator avatar

Watchers

 avatar  avatar

intensiveyandex-backend's Issues

Подправить шаблоны (как продолжение к issue "Исправить недостатки в html")

  1. Исправить дублирование пунктов меню для разного оформления. В идеале текст каждого пункта меню должен быть указан только 1 раз. Цель - минимизировать дублирование именно отображаемого страницей текста. На главную, Список товаров, О проекте (или что там по ТЗ) - пусть по одному разу только будут. Вдруг в одном месте мы поменяем название пункта меню "Каталог", а в другом забудем? Конструкцию if-else-endif можно поместить внутрь кавычек в определение свойства class, обернув этим нужные для отображения/скрытия классы.
  2. Если мы находимся на странице "Главная", крайне желательно ссылку на неё в меню делать неактивной (см. напр. класс disabled). Аналогично с другими пунктами: чтобы выглядели активными, как сейчас, но их нажатие не приводило к перезагрузке страницы. Обработку активных пунктов можно делать как через with и классы bootstrap, так и через использование django-active-link (для интереса посмотри) — приму любой вариант.
  3. Зачем тебе "найти", "логин", "зарегистрироваться", если они пока не работают? Хотя бы закомментируй, если подозреваешь, что пригодятся. Хотя на гитхабе закомментированный код не особо приветствуется, но здесь на перспективу допустимо. Главное — отсутствие нерабочих элементов на странице
  4. Нет лого сайта — это то, что должно быть в шапке сайта (обычно в левой её части)

Плюсы:

  • Как отформатировал код — вообще каеф, фронтендеры мало к чему придерутся.
  • Есть котик на глагне

Карточки товаров хардкод, но пока допущу, в базу чуть позже полезть должны.

И (совсем дополнительно) поискать, как брать актуальный для пользователя год, чтобы помещать его в копирайт

По ItemManager'у

.only('name', 'text', 'category_id', 'category__name')
А нам 'category_id' правда надо?

ItemManager в models.py:
return query_set # noqa
???

Больше тестов богу тестов!

https://github.com/Prrromanssss/LyceumYandex_django/blob/59b28742c192137575cc2b37683eeaa4c61b7ab5/lyceum/catalog/tests.py#L4
Что тесты что-то пропустили, указано в issue к urls.
Положительные, отрицательные, ноль/нули, строки с ведущим нулём/нулями, смешанные строки (начинающиеся с числа, с буквы, со спецсимвола, заканчивающиеся ими же и содержащие их посередине в разных вариациях)...

Можно лучше: Доприведем в порядок .env

https://github.com/Prrromanssss/LyceumYandex_django/blob/eb95a342ee46a609a494beab07b7b5e65d1a3dbf/env_example.txt#L1
Пример примером, но пробелы вокруг = не нужны. Как не нужны и кавычки, там все значения строковые.
И, если называешь файл что-то-там-example, а не что-то-там-var-datatype-instruction, лучше сразу дать этот example, а не загадочную всё же инструкцию по типам данных. Представь, что сам впервые видишь проект и читаешь к нему инструкцию, всё должно быть максимально просто и логично. Например, SECRET_KEY=YOUR_SECRET_KEY_123 и DEBUG=True

Проверить валидаторы

https://github.com/Prrromanssss/LyceumYandex_django/blob/eb95a342ee46a609a494beab07b7b5e65d1a3dbf/lyceum/catalog/models.py#L25
https://github.com/Prrromanssss/LyceumYandex_django/blob/eb95a342ee46a609a494beab07b7b5e65d1a3dbf/lyceum/catalog/models.py#L45
Ты точно валидаторы MinLenValidator собирался использовать?..
Это не говоря об условиях (например, условие про 2 символа я в ТЗ не нашёл ☝️)

Для инфо: Беглый взгляд на тесты

https://github.com/Prrromanssss/LyceumYandex_django/blob/eb95a342ee46a609a494beab07b7b5e65d1a3dbf/lyceum/catalog/tests.py#L19
Почти оптимально. Кому-то не понравится, как списки хранятся или ещё что, но в целом очень гуд.
В зависимости от соотношения оптимизация/информативность можно остановиться на этом или объединить этот абзац с последующим, добавив перед этим один for и скорректировав то, что передается в скобках .subTest()
Но меня и так устраивает :)

Можно чуть дополнить модель Profile

Смотрю в качестве решения основной части (расширение через 1:1, оно же o2o) - в этом плане ок
Разве что можно дообезопаситься в части birthday дополнительным blank=True
А в реальном проекте по необходимости ещё валидация была бы навешана (но здесь это не нужно)

Можно лучше: Уточнить имя функций, использовать subTest

https://github.com/Prrromanssss/LyceumYandex_django/blob/59b28742c192137575cc2b37683eeaa4c61b7ab5/lyceum/catalog/tests.py#L5
Почему test_negative_endpoins? Тестирует только отрицательные значения? Нет, тестирует на неподходящие значения. Ищем в словаре нужное слово, переименовываем.
И почему это противопоставляется test_static_endpoints? Мы разве противопоставляем тестирование статических урлов динамически генерируемым? Вроде, нет.

И раз мы так разбиваем, что везде сравниваем ответ с одним и тем же статусом (в одной функции - 200, в другой - 400; а значит, и проверка типовая-аналогичная), посмотри в сторону subTest.

Переделать тесты на модели

https://github.com/Prrromanssss/LyceumYandex_django/blob/eb95a342ee46a609a494beab07b7b5e65d1a3dbf/lyceum/catalog/tests.py#L36
Название тестов не отражает их содержание.
Где нужна валидация, использовать менеджер контекста (with self.assertRaises(ValidationError)).
Здесь тоже можно в subTest, но не обязательно, и так задач много.

Проверяем добавление одного из требуемых слов, второго, можно обоих сразу (но не обязательно), и фразы без этих слов.

А что будет, если в описании будет строка типа "Это роскошно!"?
Протестируй, вдруг выявятся ещё какие-то недостатки

Разобраться с добавлением/редактированием/удалением изображений в админке

При создании поля превью в Item требуются название, категория, тег... ещё и слова обязательные требует... мы точно превью создаем, а не экземпляр Item? o_O
Ещё и ошибки возникают, если создать с тем же превью, например
Что-то работает вообще совсем не так, как надо. Попробуй-ка сам насоздавать разных вариантов

При создании Item мы должны иметь возможно задать ему главную картинку + галерею из картинок.
И не надо заставлять пользователя/админа перед этим отдельно заносить картинку в базу. Подумай над отдельными моделями для этого

Как думаешь, может стоит создать отдельную модельку для изображения, от него унаследовать модель главного изображения и модели изображения для галереи?
Вдруг это даст какие-то новые возможности помимо того, что единообразнее работа с изображениями будет?
В итоге мы должны удобно добавлять/изменять/удалять изображения прямо из карточки создания/редактирования товара

Кстати, Preview и Gallery логичнее будет унаследовать от общего предка, не находишь?

По ERD

Между Tag и Item связь m:n, верно? От catalog_tag к вспомогательной таблице catlog_item_tags вилка не в ту сторону.

На варианты указания типов данных (char/varchar, int/bigint/smallint,..) и ограничения типов про конкретным БД сейчас не обращаю внимания, важнее смысл. Остальное подтянется, к тому же зависит от типа БД.

Уточни этот момент и приму, здесь спокойно 3 балла будет, только сделай быстро

Пара моментов по send_mail() в feedback()

  1. С переменными окружения - хорошо, что попробовал, но стоит отрабатывать получение переменных в сеттингс, а во вьюху транслировать данные уже из сеттингс. Что-то изменится в проекте, расширится или выделится - и может быть непросто с выискиванием таких моментов
  2. Ну такое просто отправлять юзеру на указанную им почту письмо с текстом его же отзыва) Хоть допиши, мол, "спасибо тебе, юзернейм, за отзыв, который ну вот такой мы получили"

Массовая рассылка копипастом (возможно, конкретно у тебя это уже есть)

Буду рад, — кто ещё так не делает, — если кроме обязательных миграций и фикстур будете прикладывать пример БД (как во 2-й лекции упоминалось), это немного сокращает время проверки.
А в ридми указать, что приложена тестовая БД чисто для знакомства с её структурой и с админкой.
Ну и данные учётки тестового админа не забыть указать. Спасибо)

Subtests

Я добавил субтесты и перебрал url в цикле, посмотри, пожалуйста, так лучше выглядит или нет?
Файлик catalog.tests.py

Разобраться со стилем кавычек и постановки скобок

https://github.com/Prrromanssss/LyceumYandex_django/blob/eb95a342ee46a609a494beab07b7b5e65d1a3dbf/lyceum/catalog/models.py#L13

  1. Зачем использовать кавычки для многострочных конструкций, если у нас короткая строка?
  2. Не забывай, как себя ведут отступы последующих строк многострочных конструкций.
  3. Если есть проблема с нехваткой длины строки, посмотри ещё в сторону других стилей расстановки скобок

Уточнить содержимое карточки товара

Категорию в карточке товара на странице списка указывать не надо, внимательнее смотрим ТЗ
Поэтому, поскольку используем одну и ту же карточку, надо добавить в неё условия. Как минимум, это условие "если на странице списка, не показывать в карточке категорию"
А ещё вполне стоит использовать эту же карточку и на странице конкретного товара, чтобы не плодить код, - просто поставив условием отображения в ней полного описания то, что мы на странице отдельного товара

Очень плохо, что в карточках нет перехода на конкретную карточку товара
Ладно, мы с тобой, можем ввести число в адресную строку, а представь человека за 60, he/she-то что делать будет

Кстати, попробуй перейти на карточку товара. Всё ли работает? ;)

И жалко, что в карточках нет изображений, согласись. Может, уже стоит добавить? (хоть этого пока и нет в задании)

Не обязательно, но можно ещё продублировать в карточке товара ссылку на возврат в список, будет не страшно

А вот такие вещи упрощать надо:

          {% if forloop.last %}
              {{ tag.name }}.
          {% else %}
              {{ tag.name }},
          {% endif %}

зачем повторять {{ tag.name }}, если вопрос только в знаке?

Исправить недостатки в html

https://github.com/Prrromanssss/LyceumYandex_django/blob/2f4be47126cfd337be968f9560079a7a00f94f04/lyceum/templates/about/index.html
Проверь все генерируемые страницы, возможно какая-то даст сбой. Например, about.

Подскажу один из вариантов поиска ошибок:
Запускаешь сервер Django, открываешь в браузере для каждой из сгенерированных основных страниц исходный код (обычно Ctrl+U).
Валидируешь здесь или здесь, например.
Вывалится ряд ошибок, которые надо исправить. Для каждого недостатка в коде будет указано, где он встретился, приоритет, что стоит сделать и в чём может быть проблема, если всё оставить, как есть.

Другой вариант — использование специальных аддонов.

Дополнительно:
Мне бы хватило банального Lorem ipsum, а так какой-нибудь lindeal (или у кого они это спёрли) подадут на авторские, когда репо откроешь для портфолио.
Якорь на Марка Цукерберга ведёт в никуда, фу так делать)
Странно, что в сгенеренном коде <!DOCTYPE html> идёт только 3-й строчкой
Так-то мы не фронтендеры и не про дизайн особо, но это то, что прям в глаза бросается

Можно лучше: Использовать именование в файлах адресов приложений

Скорректировать оформление, как в части вёрстки, так и в части оформления кода

По вёрстке собо не смотрю, всё же у нас бэк, а не фронт. Но даже в прототипировании стоит быть аккуратнее
На странице about что-то как-то всё липнет к краю окна бразуера. Думаю, как-то container надо правильно использовать

Также мелкий момент по оформлению, но уже не темплейтов: элемент словаря контекста где-то заканчивается запятой, где-то нет, выбери какой-то один стиль

Дополнительно по отображению
Не помешает текст-заглушка, когда товаров для вывода нет

Исправить импорты

https://github.com/Prrromanssss/LyceumYandex_django/blob/eb95a342ee46a609a494beab07b7b5e65d1a3dbf/lyceum/core/admin.py#L1
Приберись в импортах. Лишнее убрать или на время разработки F401 можно в ignore конфига добавить (там указал). Отсортировать импорты по строкам, с нужной отбивкой пустыми строками, и по порядку в рамках строк.
Про pip install flake8 pep8-naming flake8-broken-line flake8-return flake8-isort для самостоятельного тестирования, чтобы мне к этому не возвращаться, я уже говорил

Упорядочить внутренности моделей

https://github.com/Prrromanssss/LyceumYandex_django/blob/81caed7d7656a5ffc98857027fc0e4a456e86f2a/lyceum/core/models.py#L12
Почитай про порядок всего внутри модельки
В частности это:

The order of model inner classes and standard methods should be as follows (noting that these are not all required):
    All database fields
    Custom manager attributes
    class Meta
    def __str__()
    def save()
    def get_absolute_url()
    Any custom methods

Убрать лишнее

https://github.com/Prrromanssss/LyceumYandex_django/blob/eb95a342ee46a609a494beab07b7b5e65d1a3dbf/setup.cfg#L9
Зачем сейчас per-file-ignores? Любое дополнительное исключение должно быть обоснованно. Сейчас причин нет:

  1. Директорию */migrations/ уже обрабатывает exclude выше.
  2. С сеттингс ты и так справляешься (пока мешала та строка, которую ты спокойно перенес; это я про ту, о которой упоминал на встрече, что по красоте её можно обернуть в скобки в сишном стиле, чтобы вторая часть начиналась там же, где и первая). Тем более, что *settings.py не самое корректное написание.

Там скорее в ignore можно для удобства добавлять F401 на время разработки, т.к. джанго любит создавать файлы уже с заготовками импортов

Мелочь по Feedback.short_text()

    def short_text(self):
        return f'{self.text[:10]}...'

Отзыв из 1 буквы - всё равно будет многоточие после неё
(А ещё 10 букв на практике было бы маловато)

Уточнить классы и их имена классов

https://github.com/Prrromanssss/LyceumYandex_django/blob/eb95a342ee46a609a494beab07b7b5e65d1a3dbf/lyceum/core/models.py#L4
CommonFieldsNameIsPublished - не очень воспринимается, когда упоминаешь при наследовании.
Во-первых, это Model, а не Fields, и название должно говорить об этом. Во-вторых, это некая базовая модель, ну или абстрактная.
Поэтому в твоем случае даже что-то типа IsPublishedNamedBaseModel будет логичнее.

Но здесь стоит подумать ещё вот о чём. Вроде бы у нас есть ТЗ, но там не указано про уникальность name.
Но логически же имена тегов и категорий должны быть уникальны, разве нет? А вот с Item - вопрос, в реальности названия могут совпадать.
Поэтому подумай на свой выбор, как лучше с этим поступить (выносить или переопределять, в каком случае дублирование кода будет более избыточным).

Оптимизировать тесты

Начнем с того, что они достаточно разрослись, чтобы их разбить на отдельные модули
Создаём вместо такого растолстевшего tests.py папку tests в соответствующем приложении и там располагаем всякие test_models.py, tests_urls.py, tests_views.py и подобные им (почитай, какие имена файлов отлавливает Django unittest, чтобы в них искать тесты для запуска)
В этом случае чётко разделяем, где тестируем доступность самих урлов, где вывод вьюх, где особенности моделей (напр., валидацию)

Где-то ещё теперь в старые места можно вписать адресацию с reverse.

~

Кстати, можешь обратить внимание, что где-то что-то повторяет. Например, этот кусок:

        response = Client().get(reverse('homepage:home'))

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

А разделенные одиночные subTest ну как-то не оч

Можно улучшить админку users

Для единообразия можно было бы снова задекорировать класс в админке users, немного поменяв последовательность блоков кода
Но это некритично

В users.admin сейчас две строчки импортов из django.contrib.auth.admin - сразу вопрос: почему отдельно?
Но сначала почитай, как соотносятся User из from django.contrib.auth.admin и из from django.contrib.auth.models
Может, прослойки из ...auth.admin можно вообще избежать?

Исправить использование verbose_name

https://github.com/Prrromanssss/LyceumYandex_django/blob/eb95a342ee46a609a494beab07b7b5e65d1a3dbf/lyceum/core/models.py#L9
Можно уменьшить количество кода, если указывать verbose_name на 1-м месте, как предлагает сама официальная документация (это не подойдет только для полей ForeignKey, ManyToManyField и OneToOneField). И это не надо считать неединообразным подходом. Лучше единообразить порядок полей в моделях :)
И там же написано про конвенцию наименования verbose_name.
Заодно по другим местам посмотри на help_text, в нем первая буква автоматически не капитализируется.

Можно лучше: Уточнить имена полей

https://github.com/Prrromanssss/LyceumYandex_django/blob/eb95a342ee46a609a494beab07b7b5e65d1a3dbf/lyceum/core/models.py#L22
Можно не придумывать замену слову, "слаг" вполне себе устоявшийся термин, пусть и узкоспециализированный. Если режет глаз, можно оставить английский вариант.
Про правила написания verbose_name упомняул в другом issue.

Уточнить help_text'ы, где необходимо

https://github.com/Prrromanssss/LyceumYandex_django/blob/eb95a342ee46a609a494beab07b7b5e65d1a3dbf/lyceum/catalog/models.py#L18
А надо ли такие описания? Атрибут help_text используется не только для отображения текста в админке, так и может быть использован для дальнейшего вывода на страницу через ModelForm. А если там это будет реализовано через другие контролы (например, чекбоксы)? Пока достаточно будет чего-то типа "Выберите теги". Ну и в других всех местах уточни, где надо.

Упорядочить элементы

https://github.com/Prrromanssss/LyceumYandex_django/blob/eb95a342ee46a609a494beab07b7b5e65d1a3dbf/lyceum/catalog/admin.py#L3
Про порядок импортов вроде где-то упомянул, но и здесь напишу.
Заодно здесь ж скажу, что самому будет быстрее видеть общую картину, если развернутые описания @admin.register() будут расположены ниже кратких. Это уже, как нам преподы говорили, вкусовщина, но и факт.

Доработать тесты

https://github.com/Prrromanssss/LyceumYandex_django/blob/1307e9f8e5ff1d463ba59a3ad783db5ccf7fd1b8/lyceum/catalog/tests.py#L54
Попробуй в test_without_needed_words() указать одно норм значение, а в test_with_needed_words() - одно не норм. Помотри, что выдадут тесты.
У меня получается, что сразу вывалилось несколько failures, а так не должно быть (всего одно вхождение должно было посыпаться и сказать, какое).

Исправить тестирование в workflow (фактически тесты не запускаются!)

https://github.com/Prrromanssss/LyceumYandex_django/blob/59b28742c192137575cc2b37683eeaa4c61b7ab5/.github/workflows/django.yml#L30
Загляни ручками в GitHub Actions -> Django CI > Run Tests и подумай, почему тесты не проходят:
Ran 0 tests in 0.000s
Должны запускаться и проходить. Вспоминаем команды для работы с директориями в консоли.

Разобраться с иерархией темплейтов

Карточка товара используется более одного раза, но относится к каталогу (при этом незначительную вариативность в ней можно задать условными конструкциями).
Скажу своё субъективное мнение, а дальше смотри сам. Здесь случай мелкий, но я всё равно бы руководствовался логикой архитектуры отделимого приложения.
Если главная хочет использовать это приложение - это её проблемы, пускай идёт в него. Это не особо повод поднимать инклюд карточки до уровня проекта.
Поэтому лично мой вариант - инклюд на уровне приложения (templates/catalog/includes/card.html).
В другом случае я бы подумал об обоснованности того или иного решения с учётом сути проекта.

Исправить регулярное выражение для адресов приложения catalog

https://github.com/Prrromanssss/LyceumYandex_django/blob/59b28742c192137575cc2b37683eeaa4c61b7ab5/lyceum/catalog/urls.py#L7
Что-то немного не то с регуляркой (и я такое уже видел).
/catalog/01 (или /catalog/001) пропускает наряду с /catalog/1, но при этом не пропускает что-то типа /catalog/010, хотя пропускает /catalog/10 :)
Вообще, так-то элементы с ведущими нулями пропускать не оч (в частности, в данном случае). Убираем, чтобы не пропускало. Опять же, и задачу это немного упростит ;)

Упорядочить код в forms

Во-первых, импорты
Дважды django.contrib.auth.forms - можно объединить, и as этому не помеха
Только проверь, чтобы линтеры не ругались

Во-вторых, по формам
Сейчас перемудрил, можно упростить. Но прежде всего пока будем ориентироваться, чтобы работало
Кстати, загляни сюда, возможно позаимствуешь что-то полезное:
https://github.com/Capwell/extend_user_model_django
Конкретно если по 1:1, это здесь:
https://github.com/Capwell/extend_user_model_django/tree/main/one_to_one/users

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.