Да, скоро это уже не совсем актуально станет (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 %}
{{ comment.comment }}
{{ comment.name }}, {{ comment.submit_date }}
{% endfor %}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',
),
...
Комментариев нет:
Отправить комментарий