Django: CBV или функции?

Есть ли какие-нибудь общепринятые правила написания views?
Не будет ли плохим тоном, если в одном views будут и классы, и функции?
Классы удобны, например, ListView или DetailView, но чтобы добавить в контекст дополнительные данные,
приходится писать несколько строк get_context_data, и кода получается больше, чем в обычной функции
  • Вопрос задан
  • 3215 просмотров
Решения вопроса 3
aRegius
@aRegius
Python Enthusiast
Я не столь многоопытен в Django, но имеющейся информацией поделиться готов. Возможно, вам также пригодится...

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

Это Daniel & Audrey Roy Greenfeld, авторы небезызвестной Two Scoops of Django и Arun Ravindran, developer member of the Django Software Foundation и автор Django Design Patterns and Best Practices.

И первые, и второй предпочитают CBV. Но это, в большей степени, личные предпочтения. Сами Гринфилды отмечают, что знают немало своих коллег, предпочитающих работу с FBV (цитирую: "...Some developers prefer to err on the side of using FBVs for most views and CBVs only for views that need to be subclassed. That strategy is fine as well...."). Одним словом, это действительно вопрос личных предпочтений и характера разрабатываемого продукта.

Единственный категорический совет от них - не использовать CBV для написания обработчиков ошибок ("...Don’t use CBVs to write custom 403, 404, and 500 error handlers. Use FBVs instead....")

А тут можно полюбопытствовать на графическую подсказку от Гринфилдов по выбору предпочтения в зависимости от стоящих перед вами задач.
Ответ написан
Комментировать
@deliro
Только CBV.
Каждый метод имеет свой смысл, не всё вперемешку.
Можно юзать миксины.
Можно наследоваться.

Не будет ли плохим тоном, если в одном views будут и классы, и функции?

Я сразу отправляю переделывать.

Чтобы добавить N элементов в контекст, нужно написать N+2 строки. Это всего на 1 больше, чем у вьюхи-функции:
def get_context_data(self, **kwargs):
    kwargs['your_additional'] = 'context_here'
    return super().get_context_data(**kwargs)


В большинстве случаев используются Generic Views или миксины вроде FormMixin. Очень редко я наследуюсь только от View.
Ответ написан
Комментировать
sim3x
@sim3x
KISS

Если перед тобой типовая задача, которая реализуется в 1-5 строк на CBV -> используем CBV
Если ты уже видишь, как будешь пилить из CBV пятиетажное наследование для "упрощения" -> FBV

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

def get_common_context():
     # do something
     return {'answer': 42, 'foo': 'bar'}


def index_page(request):
     context = get_common_context()
     context['buzz'] = 123
     return render(request, 'index.html', context)
 

class MyCommonContext(ContextMixin):
    def get_context_data(self, **kwargs):
        context = super(RandomNumberView, self).get_context_data(**kwargs)
        # тут нужно определиться, какой контекст главнее и тот должен быть последним
        context.update(get_common_context())
        context['buzz'] = 123
        return context


class ArticleDetailView(MyCommonContext, DetailView):
    model = Article
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@evikbook
DevOps
Лучше CBV, на них меньше копипаста получается (а в идеале 0), больше продуктивность и КПД от каждой строчки кода. Единственное выделите день на то, чтобы мозги свои переконфигурировать под них (сделайте мини проект)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы