2016-01-03 4 views
0

Чтобы узнать больше о Django и понять, как программировать как можно более сухой, я строю небольшой сайт с несколькими особенностями:Включить форму в нескольких шаблонах для GenericForeignKey модели (ОЦК)

  • сообщение Блог
  • сообщение изображение
  • сообщение Закладка

на каждом объекте в этих АРР, пользователи могут оставлять комментарии. Поэтому я получил комментарий APP с моделью, которая использует GenericForeignKey. (Правильная работа)

Я хочу отобразить форму комментария в подробном представлении блога, изображения и закладки. Чтобы сохранить этот сухой, я создал включение тег

@register.inclusion_tag('comments/add_comment.html') 
def show_comment_form(obj): 
    pk = obj.pk 
    content_type = ContentType.objects.get_for_model(obj) 
    form = AddCommentForm() 

    return {'pk': pk, 'content_type': content_type, 'form': form} 

который использует следующий шаблон для визуализации формы:

<form action="{% url 'comments:add' pk content_type %}" method="post"> 
    <div class="create-blog-container"> 
     <div class="box-top">{% trans "Leave your comment behind" %}...</div> 
     <div class="box-content"> 
      {% csrf_token %} 
      {{ form.as_div }} 
     </div> 
     <div class="box-footer"> 
      <input type="submit" class="btn btn-green" value="{% trans 'Add comment' %}" /> 
     </div> 
</form> 

При добавлении

{% show_comment_form blog %} 

В шаблоне подробно блога , он отображает форму с правильными параметрами. Когда я нажимаю кнопку SUBMIT, форма обрабатывается в следующем Add view (в настоящее время только принимает форму, проверяет и добавляет ее в базу данных через службу).

class Add(LoginRequiredMixin, View): 
    model = Comment 

    def post(self, *args, **kwargs): 
     content_type = self.kwargs.get('content_type') 
     pk = self.kwargs.get('pk') 
     form = AddCommentForm(self.request.POST) 

     if form.is_valid(): 
      content = form.cleaned_data.get('content') 
      comments.services.comment.add(content_type, pk, self.request.user, content) 
      messages.add_message(self.request, messages.SUCCESS, _("Your comment has been posted")) 
     else: 
      print(form.errors) 

     return HttpResponseRedirect(reverse('blogs:detail', kwargs={'pk': pk})) 

Но это решение не возвращает форму с ошибками проверки. Я вернулся к основам, чтобы создать «жестко запрограммированную» форму в подробном представлении блога, но она не является гибкой и не сухим.

Может ли кто-нибудь дать мне толчок в правильном направлении, как преобразовать эту форму (через тег включения или другой предложенный метод) в сухую и гибкую форму, чтобы опубликовать комментарий к общему типу content_type?

ответ

0

Для того, чтобы закончить DRY, я предлагаю (как вы упомянули), комментируя Django contenttypes и смешивая его с AJAX.

Еще один для вашего случая это можно пройти проверенную форму вам включение метки (show_comment_form)

@register.inclusion_tag('comments/add_comment.html') 
def show_comment_form(obj, form=None): 
    pk = obj.pk 
    content_type = ContentType.objects.get_for_model(obj) 
    form = form or AddCommentForm() 

    return {'pk': pk, 'content_type': content_type, 'form': form} 
0

Изменить ваше включение тега, поэтому он будет оставлять комментарий для по разной URL, в зависимости от типа объекта. Также измените его, поэтому он не будет создавать новую форму, если в текущем контексте уже есть comment_form. Пример:

@register.inclusion_tag('comments/add_comment.html', takes_context=True) 
def show_comment_form(context, obj): 
    pk = obj.pk 
    content_type = ContentType.objects.get_for_model(obj) 
    form = context.get('comment_form', AddCommentForm()) 

    url_id = "%s:%s:comment:add" % (content_type.app_label, content_type.model) 

    return {'pk': pk, 'content_type': content_type, 'form': form, url_id} 

шаблона:

{# content_type may be obsolete now #} 
<form action="{% url url_id pk content_type %}" method="post"> 
    <div class="create-blog-container"> 
     <div class="box-top">{% trans "Leave your comment behind" %}...</div> 
     <div class="box-content"> 
      {% csrf_token %} 
      {{ form.as_div }} 
     </div> 
     <div class="box-footer"> 
      <input type="submit" class="btn btn-green" value="{% trans 'Add comment' %}" /> 
     </div> 
</form> 

Создать вид подмешать, который добавит на ваш взгляд обработки комментария создания (или форма проверки), создавать новые представления для каждого из типов контента, от нормального зрения для этот контент и ваш новый mixin и зарегистрируйте это представление по отдельному URL-адресу (имя, которое указывает, что вы создаете url_id в теге вашего шаблона).

Это сухая, гибкая и не требует много изменений.