2017-09-23 4 views
1

J'essaye de faire un clone de reddit avec django. Le problème est que je ne peux pas combiner DetailView et une vue basée sur les fonctions. Je peux créer un post et des commentaires à des articles spécifiques, mais je n'ai pas pu faire de commentaires imbriqués. J'ai créé la logique mais je n'ai pas pu la rendre. Comment rendre des commentaires imbriqués? Je ne peux pas l'esprit de données get_context_dataDjango/combinig DetailView Vues basées sur FormMixin et Function

views.py

class EntryDetail(DetailView, FormMixin): 
    template_name = 'post_detail.html' 
    model = Post 
    form_class = CommentForm 

    def get_success_url(self): 
     return reverse_lazy('post-detail', kwargs={'pk': self.object.pk}) 

    def get_context_data(self, **kwargs): 
     context = super(EntryDetail, self).get_context_data(**kwargs) 
     context['post_object'] = Post.objects.filter(pk=self.kwargs.get('pk')) 
     context['comments'] = Post.objects.get(pk=self.kwargs.get('pk'))\ 
     .comments\ 
     .all() 
     return context 

    def post(self, request, *args, **kwargs): 
     form = self.get_form() 
     p_object = Post.objects.get(pk=self.kwargs.get('pk')) 
     if form.is_valid(): 
      form.save(post=p_object.id) 
      return redirect(reverse_lazy(
          'post-detail', kwargs={'pk': p_object.pk})) 


def add_sub_comment(request, comment_id): 

    comment = Comment.objects.get(pk=comment_id) 
    if request.POST: 
     form = SubCommentForm(request.POST) 
     if form.is_valid(): 
      form.save(comment_object=comment.id) 
      return redirect('index') 

    sub_comments = Comment.objects.filter(object_id=comment.id) 
    ctx = {'sub_comments': sub_comments} 
    return render(request, 'post_detail.html', ctx) 

urls.py

urlpatterns = [ 
    url(r'^$', EntryView.as_view(), name='index'), 
    url(r'^new_post/$', EntryCreate.as_view(), name='new-post'), 
    url(r'^post_detail/(?P<pk>\d+)/$', 
         EntryDetail.as_view(), name='post-detail'), 
    url(r'^sub_comments/(?P<comment_id>\d+)/$', 
         views.add_sub_comment, name='sub-comment'), 
] 

post_detail.html

{% for comment in comments %} 
<div class="comment-per-style"> 
    {{ comment.entry_comment }} 
    {% for subcomment in sub_comments %} 
    <ul> 
     <li>{{ subcomment.entry_comment }}</li> 
    </ul> 
    {% endfor %} 
</div> 
<form action="{% url 'sub-comment' comment.id %}" method="post"> 
    {% csrf_token %} 
    <input id="entry_comment" type="text" name="entry_comment" maxlength="100" required /> 
    <input type="submit" value="OK"> 
</form> 
{% endfor %} 

forms.py

class SubCommentForm(forms.ModelForm): 

    class Meta: 
     model = Comment 
     fields = ('entry_comment',) 
     widgets = { 
      'entry_comment': forms.TextInput(attrs={'class': 'form-input'}), 
     } 

    def save(self, comment_object): 
     comment = Comment() 
     comment.entry_comment = self.cleaned_data['entry_comment'] 
     comment.object_id = comment_object 
     comment.content_type_id = 7 
     comment.save() 

    def __init__(self, *args, **kwargs): 
     super(SubCommentForm, self).__init__(*args, **kwargs) 
     # deleted form label 
     self.fields['entry_comment'].label = "" 

models.py

class Comment(models.Model): 
    entry_comment = models.TextField(max_length=160) 

    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey('content_type', 'object_id') 

    def __str__(self): 
     return self.entry_comment 

class Post(models.Model): 
    subject = models.CharField(max_length=20) 
    entry = models.TextField(max_length=160) 
    comments = GenericRelation(Comment) 

    def get_absolute_url(self): 
     return reverse('index') 

    def __str__(self): 
     return self.subject 
+0

montrer votre 'modèles comment' Veuillez –

+0

J'ai ajouté mes modèles. –

Répondre

0

Vous pouvez:

dans les modèles ajouter méthode sub_comments

class Comment(models.Model): 
    entry_comment = models.TextField(max_length=160) 

    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey('content_type', 'object_id') 

    def __str__(self): 
     return self.entry_comment 

    def sub_comments(self): 
     ct = ContentType.objects.get_for_model(self) 
     childs = Comment.objects.filter(content_type=ct, object_id=self.pk) 
     return childs 

    def descendants_comments(self): 
     ct = ContentType.objects.get_for_model(self) 
     childs = Comment.objects.filter(content_type=ct, object_id=self.pk) 
     result = [] 
     for child in childs: 
      result.append(child) 
      result.append(child.descendants_comments()) 
     return result 

et l'utiliser dans le modèle:

 {{ comment.entry_comment }} 
     {% for subcomment in comment.sub_comments %} 
         <!-- ^^^New^^^--> 
     <ul> 
      <li>{{ subcomment.entry_comment }}</li> 
     </ul> 
     {% endfor %} 
+0

merci beaucoup. J'aurais dû lire correctement les docs. –

+0

Je veux voir les commentaires dans les commentaires comme reddit. devrais-je changer ma logique de formulaire? pourriez-vous me donner des conseils? –

+0

désolé ne comprends pas, ce que tu veux dire 'comme reddit'? –