LINUX.ORG.RU

Философия Django

 , ,


0

3

Привет!

Надоело просто так скучать на изоляции, решил изучить Django.
Что с самого начала бросается в глаза - везде строки и динамические атрибуты. Почему так? Это же неудобно ни разу

from django.contrib import admin
from . models import Bb

class BbAdmin(admin.ModelAdmin):
    list_display = ('title', 'content', 'price', 'published')
    list_display_links = ('title', 'content')
    search_fields = ('title', 'content')
А можно было бы:
class BbAdmin(admin.ModelAdmin):
    list_display = (Bb.title, Bb.content, Bb.price, Bb.published)
...

Другой пример:
mm = MainModel.objects.get(pk=1)
another = mm.linked_set.filter(pubdate_lt=date)

Почему не:
mm = MainModel.objects.get(pk=1)
another = mm.set(Linked).filter(lt(Linked.pubdate, date)

Или вот ещё, банальные url'ы:
urlpatterns = [
    path('polls/', include('polls.urls')),
]

Заменить на:
from . polls import urls as purls
urlpatterns = [
    path('polls/', include(purls)),
]

Ну и в таком духе. Да, где-то получится писать чуть больше, но зато такой код будет инспектируемый, легко проверяемый и поддерживаемый. Если где опечатался это видно сразу, прямо в IDE. Да банальное автоматическое дополнение!

Или я не понимаю что-то?

★★★★★
Ответ на: комментарий от anonymous

Я считаю, что не стоит. Но рабисты тебе, конечно, скажут, что раби учить стоит.

dimuska139 ★★
()
Ответ на: комментарий от dimuska139

Но как быть, если потребуется другой тип хранилища?

Большой шанс, что под другой тип хранилища всё равно архитектуру приложения сильно придётся перепиливать, особенно сервисный слой. Вот если хочется использовать несколько видов хранилищ одновременно (для кэша или сбора статистики, например), то тут да - настаёт жопа. Приходится либо держать несколько моделей, либо делать обёртки поверх ORM.

Из-за этого невозможно сделать сервисный слой независимым от фреймворка - модель Active Record будет проходить через все слои приложения.

Тоже не самая большая проблема: переписывать с одного фреймворка на другой всегда сложно и сколько не видел – чаще всего всё равно перепиливают сервис целиком.

А вообще, это старый срач «больше абстракций, гибче и больше кода vs. проще, быстрее и деревяннее».

oldstable
()
Ответ на: комментарий от dimuska139

ну, да. современные приложения - это вуй либо реакт + апишка, лучше по стандарту со swagger’ом либо graphql. а зачем тебе aiohttp нужен? он так-то быстрее примерно в полтора-два раза будет работать чем на flask, но геморрой с отладкой того стоит (проблема с автокомплитом во всех популярных ide)?

tz4678 ★★
()
Последнее исправление: tz4678 (всего исправлений: 1)
Ответ на: комментарий от tz4678

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

Едрить вы квалифицированный специалист.

oldstable
()
Ответ на: комментарий от tz4678

Дело в том, у меня просто не apiшка, а граббер, который дергает апихи другого сайта (очень дофига запросов) и пишет это все в мою базу. При этом нужно ежедневно, дергая эти же API, актуализировать данные. Также нужно скачивать картинки, делать к ним миниатюры и лить все это в S3. Дохрена сетевых запросов, в общем. Пробовал изначально синхронно это делать, но работало крайне медленно. Написал говноскрипты на aiohttp - и все стало реально быстро работать. Но качество моего кода такое себе получилось, потому что я вообще не особо питонщик, только на Django писал. Вот думаю, как сделать по-нормальному. Была мысль даже Scrapy прикрутить, но не хотелось бы проект на его основе пилить - мне кажется, недостаточно гибко будет.

P.s. изначально написал про API на aiohttp просто чтобы не вдаваться особо в подробности

dimuska139 ★★
()
Последнее исправление: dimuska139 (всего исправлений: 2)
Ответ на: комментарий от oldstable

Тоже не самая большая проблема: переписывать с одного фреймворка на другой всегда сложно и сколько не видел – чаще всего всё равно перепиливают сервис целиком.

А тесты не приемочные удобно писать? Неудобно ж везде ORM мокать.

dimuska139 ★★
()
Ответ на: комментарий от dimuska139

Для AR/DM обычно считают, что сама ORM протестирована и получение/запись данных и прочий CRUD тестировать не нужно. Логику вокруг записей можно вполне тестировать на реальной СУБД.

oldstable
()

Это для того чтоб небыло рекурсии..

dem ★★
()
Ответ на: комментарий от oldstable

Тут не поспоришь, но я не про тестирование конкретно ORM, а про покрытие юнитами того же сервисного слоя. Если говорить не про приемочные тесты, то мокать ORM в любом случае придется.

Приемочные тесты тоже нужны, безусловно, но делать обвязку для запуска тестов на реальной СУБД не всегда просто. К тому же, по-хорошему, тесты должны быть независимы, так что нужно перед каждым тестом пересоздавать базу и накладывать фикстуры. То есть такие тесты тяжелые и медленные. Это я к тому, что приемочные тесты юниты не заменяют. А юниты на реальной базе никто не гоняет.

И, да, использование реальной базы для тестов не позволяет запускать группы тестов параллельно.

dimuska139 ★★
()
Ответ на: комментарий от anonymous

стоит ли руби сейчас учить или он помер?

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

Nervous ★★★★★
()
Ответ на: комментарий от dimuska139

так что нужно перед каждым тестом пересоздавать базу и накладывать фикстуры

Ну до такого не доходит. БД не пересоздаётся, обычно накладываются только та часть фикстур, что нужна для конкретной группы тестов или теста. Но, естественно, для каждой ORM уже написано куча костылей для mock’ов, ещё и каждый проект обязательно имеет свои, вплоть до разворачивания моков из фикстур.

А юниты на реальной базе никто не гоняет.

Гоняют таки. Просто работает это всё долго. :) Кому-то, наоборот, нравится именно так.

oldstable
()
from . models import Bb

class BbAdmin(admin.ModelAdmin):
    list_display = ('title', 'content', 'price', 'published')
    list_display_links = ('title', 'content')
    search_fields = ('title', 'content')

Двумя буквами, как правило, модели не называют, в основном букв 10-20. Получается много писанины. Вот пример:

from django.contrib import admin
from . models import AccountRequest

class AccountRequestAdmin(admin.ModelAdmin):
    list_display = (AccountRequest.title, AccountRequest.content, AccountRequest.price, AccountRequest.published)

Другой пример: mm = MainModel.objects.get(pk=1) another = mm.linked_set.filter(pubdate_lt=date)

Почему не: mm = MainModel.objects.get(pk=1) another = mm.set(Linked).filter(lt(Linked.pubdate, date)

Если нужна алхимия, то нужно брать алхимию. Но мне за 10 лет работы с джангой алхимия 1 раз всего нужна была. Джанговский ОРМ проще синтаксис.

[quote]Ну и в таком духе. Да, где-то получится писать чуть больше, но зато такой код будет инспектируемый, легко проверяемый и поддерживаемый. Если где опечатался это видно сразу, прямо в IDE. Да банальное автоматическое дополнение/quote

Вообще такой проблемы нет. Не так часто структура базы данных меняется + пишутся всегда тесты. Ошибку очень легко выловить

dicos ★★
()
Последнее исправление: dicos (всего исправлений: 1)
Ответ на: комментарий от WitcherGeralt

Flask-restless нужен только для того, чтобы быстро сгенерировать CRUD

Ой, да, глупый вопрос был. Посмотрел, и сам быстро понял что это совсем не то.

Более того, я почитал про flask-restx, подумал, и сейчас думаю что мне вообще все эти API, json не нужны :) Мне просто нужно туда-сюда передавать шифрованные данные. Я думаю действительно всё сам сделать.

Но всё равно, спасибо!

Вся соль использования микрофреймворка в том, что можно сделать всё по-своему под свой собственный кейс.

Я тут нуб, но многое уже сделал, и кажется что эти слова - вот про меня! Все нужные внутренние кишочки – под рукой, всё что надо – сам руками подстроил. (ну вот вчера админу сделал доступ из-под юзера – просто подправил создание сессионной куки)

Вопрос только… неужели джанго настолько неудобна в такой кастомной подстройке?

the1 ★★
()
Ответ на: комментарий от the1

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

WitcherGeralt ★★
()
Ответ на: комментарий от anonymous

https://trends.google.ru/trends/explore?geo=RU&q=%2Fm%2F06ff5,%2Fm%2F05z1_,%2Fm%2F02p97,%2Fm%2F09gbxjr

Go популярнее и проще + нет того количества портянок, которые написали петухи на самокатах, пришедшие из мира JS до этого писавшие только на jQuery и гейском Coffee Script.

UPD: богомерзкий TypeScript, придуманные шарпо*лядками, такой же маргинальный как и равин с Go-мосеком

tz4678 ★★
()
Последнее исправление: tz4678 (всего исправлений: 1)

Надоело просто так скучать на изоляции, решил изучить Django.

Хорошо у вас в двухтысячных. Но я бы лучше бетховенов намайнил.

anonymous
()
Ответ на: комментарий от WitcherGeralt

… но в целом ты будешь плясать под дудку разрабов джанги, они за тебя уже всё решили.

Нужно быть очень осмотрительным, когда тебе предлагают «бесплатный сыр» и постараться понять

А не стоит ли за ним рядом мышеловка?

Владимир

anonymous
()
Ответ на: комментарий от ls-h

Тоже из двухтысячных? У вас флешмоб?

anonymous
()
Ответ на: комментарий от tz4678

Go популярнее и проще

При этом нет по сути ни одного нормального фреймворка (gin/gonic если только) или каких-то стандартов, кроме go-kit разве что. С одной стороны, это плюс, но, с другой, у Go-разрабов настолько развязаны руки, что каждый пишет как хочет - и хрен пойми потом в этой лапше хоть что-то. Все разрабы пишут проекты совершенно по-разному. А код Goшный плохо читабелен, особенно когда его много.

Сам не люблю js, но код на том же NestJS выглядит гораздо более приятно.

dimuska139 ★★
()
Ответ на: комментарий от the1

Вдруг тебе для твоих задач это подойдёт:
https://potion.readthedocs.io/en/latest/
- мне не подошло, у меня очень витиеватый API, эта штука местами избыточна, местами не подходит.

Shadow ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.