Хорошая практика Django для добавления REST API позже, после DRY - PullRequest
0 голосов
/ 16 февраля 2019

Я запускаю веб-приложение на чистом Django.Однако в будущем может возникнуть необходимость в REST API.Если это произойдет, наиболее очевидным выбором станет DEST-среда Django.

И "старомодные", и REST-детали разделяют модели, однако представления немного отличаются (например, определения разрешений), а формы заменяются сериализаторами.Выполнение этого наиболее очевидным способом означало бы дублирование логики приложения несколько раз, и, следовательно, неспособность следовать принципу СУХОЙ, и поэтому код становится неуправляемым.

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

Теперь у меня закончились идеи.Какова лучшая практика здесь?

1 Ответ

0 голосов
/ 16 февраля 2019

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

ОбаDjango формы и сериализаторы Rest Framework уже предлагают вам декларативный подход, который абстрагирует от стандартного кода, необходимого для базовых вещей, который обычно в любом случае учитывает большую часть вашего кода.Например, одна из ваших форм Django может выглядеть так:

class ArticleForm(ModelForm):
    class Meta:
        model = Article
        fields = ['title', 'content']

И в будущем сериализатор DRS будет выглядеть так:

class ArticleSerializer(ModelSerializer):
    class Meta:
        model = Article
        fields = ['title', 'content']

Как вы можете видеть, если вы попытаетесь ипридерживайтесь ModelForm и ModelSerializer, в любом случае дублирования не будет.Вы также можете просто сохранить список полей в переменной и просто использовать это.

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

def save_article_with_author(article_data, author_data):
    # custom data manipulation before saving, consider that article_data will be a dictionary either if it comes from deserialized JSON (api) or POST data
    # send email, whatever

ThisФункция может быть разделена между вашей формой и сериализатором.

Для всего, что связано со выборкой данных, я бы постарался максимально использовать Менеджеры моделей, определяя пользовательские наборы запросов, которые можно возобновить, например, для опций форм и сериализаторов.,

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

Представьте себе такой сценарий: добавьте, например, проверки прав доступа или логику для отправки электронного письма при создании пользователя, переопределяя метод save () вашей модели Article.Затем позже вас попросят написать простую команду управления для пакетного импорта пользователей из электронной таблицы.На этом этапе то, что вы сделали в своем методе save (), действительно мешает, так как вы можете свободно получать доступ к своим данным через вашу модель, не беспокоясь о разрешениях, электронных письмах и всем этом.

Относительнослой представления и предполагая, что вам нужно реализовать некоторые общие проверки подлинности / разрешения, и вы не хотите иметь отдельные представления, вы можете использовать этот подход: https://www.django -rest-framework.org / themes / html-and-forms /

Фреймворк REST Blockquote подходит для возврата как ответов в стиле API, так и обычных HTML-страниц.Кроме того, сериализаторы могут использоваться в качестве HTML-форм и отображаться в шаблонах.

Вот несколько рекомендаций о том, как можно динамически переключаться с HTML на JSON в зависимости от типа содержимого запроса:

https://www.django -rest-framework.org / api-guide / renderers / # advanced-renderer-Использование

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

...