Да, скоро это уже не совсем актуально станет (django.contrib.comments устаревший и с версии 1.6 вынесен в отдельный проект), но решение отточилось на третьей версии и мне жалко его терять просто :) Пример тут для версии 1.5.
Вьюшки получают нужный экземпляр модели и передают в шаблоны для рендера их через стандартные теги (такова задумка оригинального приложения), см. ниже. Вьюшка postcomment помимо этого делает небольшой хак, чтобы отловить валидацию формы и постинг (используется почти полностью родной код). Я накомментил очень богато, всё должно быть понятно.
views.py
from django.contrib.auth.decorators import login_required from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseNotFound from django.shortcuts import render # Здесь мы намеренно не получаем напрямую список для рендера, т.к. хотит больше отдать # стандартному рендеру и стандартным шаблонам контриб-аппа 'comments' @login_required def listcomments(request, eid, model): # получаем объект сущности try: ieid = int(eid) # получаем сущность ct = ContentType.objects.get_for_model(model) entity = ct.get_object_for_this_type(pk=ieid) except (ValueError, KeyError): return HttpResponseBadRequest('error params') except ObjectDoesNotExist: return HttpResponseNotFound('entity %s id=%i not found' % (model.__name__, ieid)) return render(request, 'commentsajax/list.html', {"entity": entity, }) @login_required def postcomment(request, eid, model): # получаем объект сущности try: ieid = int(eid) # получаем сущность ct = ContentType.objects.get_for_model(model) entity = ct.get_object_for_this_type(pk=ieid) except (ValueError, KeyError): return HttpResponseBadRequest('error params') except ObjectDoesNotExist: return HttpResponseNotFound('entity %s id=%i not found' % (model.__name__, ieid)) # работа непосредственно if request.method == 'POST': # надо проверить юзера и мыло, чтобы форма свалидировалась # у нас не используется имя и мыло и не заполняется в форме так что считаем что пришли пустые. # но юзер проверится и поставится в оригинальном методе из полного имени или юзернема, а мыло может остаться пустым # юзер у нас всегда залогинен по определению. if not request.user.email: request.POST = request.POST.copy() request.POST["email"] = "none@none.none" # передаём управление оригинальному коду from django.contrib.comments.views.comments import post_comment response = post_comment(request) # проверяем вернутый статус if response.status_code == 302: # если редирект, то было норм return HttpResponse('ok') else: # иначе там нам рисуется ошибка, мы переопределили comments/preview.html как раз чтобы туда оно и вывелось точь-в-точь как наша форма return response # запрос формы else: return render(request, 'commentsajax/form.html', {"entity": entity, })
Эти шаблоны внутри нашего приложения рендерят через стандартные теги список комментариев и форму:
templates/commentsajax/form.html
{% load comments %} {% render_comment_form for entity %}
templates/commentsajax/list.html
{% load comments %} {% render_comment_list for entity %}
Эти шаблоны менять не нужно по моей задумке. Они нужны, чтобы максимизировать количество используемого кода оригинального приложения. Чтобы нарисовать свой список комментариев и свою форму надо менять стандартные шаблоны, например такие минимальные могут быть:
templates/comments/form.html
{% include "comments/preview.html" %}
templates/comments/list.html
{% for comment in comment_list %}{% endfor %}{{ comment.comment }}
{{ comment.name }}, {{ comment.submit_date }}
templates/comments/preview.html
{% load comments %}
Здесь form.html повторяет preview.html, который мы перегрузили чтобы отловить ошибки от формы не меняя ничего во view, ведь туда приходит ошибки по задумке оригинального приложения, напоминаю. Кнопки в форме нет, т.к. я использовал в своих примерах бутстраповские диалоги с родной их кнопкой, но суть понятна - по нажатию на неё отправляем ажаксом эту форму. Вообще с клиентской стороны запрашивается список каментов через GET. Сама форма через GET запрашивается и через POST отдаются данные, если вернулось не "ok", то значит вернулась форма с отрендереными ошибками, которые надо заново перепоказать.
Такая сложная схема в view с eid и model нужна для того, чтобы настраивать привязку комментариев на уровне url, т.к. у меня комментарии привязывались к нескольким сущностям, а в случае ajax мне лично удобнее тупо слать пост на ajax_listcomments/ и получать комментарии именно для этой сущности. Например, так у меня url настроены:
... # это обязательно надо при сохранении камента, для резолва 'comments-comment-done' внутри views оригинального аппа (r'^comments/', include('django.contrib.comments.urls')), # комментарии к проекту url(r'^project/(?P<eid>[^/]+)/ajax_listcomments/$', views_comment.listcomments, {'model': Project}, name='project-ajax-listcomments', ), url(r'^project/(?P<eid>[^/]+)/ajax_postcomment/$', views_comment.postcomment, {'model': Project}, name='project-ajax-postcomment', ), # комментарии к контрагенту url(r'^contragent/(?P<eid>[^/]+)/ajax_listcomments/$', views_comment.listcomments, {'model': Contragent}, name='contragent-ajax-listcomments', ), url(r'^contragent/(?P<eid>[^/]+)/ajax_postcomment/$', views_comment.postcomment, {'model': Contragent}, name='contragent-ajax-postcomment', ), ...
Комментариев нет:
Отправить комментарий