Это совершенно действительный для mixin, чтобы наследовать от другого mixin - фактически, именно так сделано большинство продвинутых микшинов Django.
Однако идея mixins состоит в том, ком plete, полезный класс. Прямо сейчас, ваш JSONResponseMixin
также может быть отдельным классом, на который вы не наследуете, или методы могут быть просто модульными методами. Это определенно работает, в этом нет ничего плохого, но это не идея mixin.
Если посмотреть на Джанго BaseDetailView
, вы увидите следующий метод: get()
def get(self, request, *args, **kwargs):
self.object = self.get_object()
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
get_object()
и get_context_data()
определены в подклассов BaseDetailView
, но render_to_response()
нет. Для миксинсов хорошо опираться на методы, которые суперклассы не определяют, это позволяет различным классам, которые наследуют от BaseDetailView
, предоставить свою собственную реализацию render_to_response()
. Сейчас, в Django, есть только один подкласс.
Однако логика делегирована как можно больше тем небольшим многоразовым методам, которые поставляются микстинами. Это то, к чему вы хотите стремиться. Если/еще логика избегать, насколько это возможно - самая передовая логика в представлениях Django по умолчанию является:
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
Вот почему очень схожие взгляды, как CreateView
и UpdateView
фактически два отдельных представления, в то время как они могут быть легко один вид с некоторой дополнительной if/else-логикой. Единственное отличие состоит в том, что CreateView
делает self.object = None
, а UpdateView
делает self.object = self.get_object()
.
В данный момент вы используете DetailView
, который определяет метод get()
, который возвращает результат self.render_to_response()
. Тем не менее, вы переопределяете render_to_response()
, чтобы вернуть ответ JSON вместо ответа HTML на основе шаблонов. Вы используете миксин, чтобы не использовать (SingleObjectTemplateResponseMixin
), а затем переопределить его поведение, чтобы сделать то, что вы не хотите делать, просто чтобы получить представление о том, что вы хотите. Лучшей идеей было бы написать альтернативу для DetailView
, кто только задание - предоставить ответ JSON на основе одного объекта. Чтобы сделать это, я хотел бы создать SingleObjectJSONResponseMixin
, похожий на SingleObjectTemplateResponseMixin
, и создать класс JSONDetailView
, который сочетает в себе все необходимые Примеси в единый объект:
class SingleObjectJSONResponseMixin(object):
def to_json(context):
return json.dumps(context)
def render_to_response(context, **httpresponse_kwargs):
return HttpResponse(self.to_json(context),
context_type='application/json',
**httpresponse_kwargs)
class BaseJSONDetailView(SingleObjectMixin, View):
# if you want to do the same for get, inherit just from BaseDetailView
def post(self, request, *args, **kwargs):
self.object = self.get_object()
context = self.get_context_data(object=self.object)
return render_to_response(context)
class JSONDetailView(SingleObjectJSONResponseMixin, BaseJSONDetailView):
"""
Return JSON detail data of a single object.
"""
Обратите внимание, что это почти точно так же, как BaseDetailView
а SingleObjectTemplateResponseMixin
от Django. Разница заключается в том, что вы определяете метод post()
и что рендеринг намного проще с просто преобразованием в JSON данных контекста, а не с полным преобразованием шаблона. Однако логика намеренно упрощается как можно больше, и методы, которые не зависят друг от друга, разделяются как можно больше. Таким образом, SingleObjectJSONResponseMixin
может, например, смешивать с BaseUpdateView
, чтобы легко создать AJAX/JSON-based UpdateView
. Подклассы могут легко переопределять различные части микшинов, например, переопределять to_json()
для обеспечения определенной структуры данных. Логика визуализации находится там, где она принадлежит (в render_to_response()
).
Теперь все, что вам нужно сделать, чтобы создать определенный JSONDetailView
является подкласс и определить, какую модель использовать:
class UserJSONDetailView(JSONDetailView):
model = MyUser
Как насчет слияния '' JSONResponseMixin', HandlingAJAXPostMixin' в одну примесь? – falsetru
Почему вы не сохраняете только класс JSONResponseMixin и вызываете каждый метод в любое время, когда хотите. – drabo2005
@ abda2005 Что вы имеете в виду точно ...? – user2492270