Django MPTT, не удается получить parent_id для ответа на потоковый комментарий

Мои проблемы следующие:

Я относительно новичок в Django. так что извините за этот беспорядок. Я пытался реализовать потоковые комментарии в своем блоге через MPTT. Но когда я нажимаю кнопку 'Reply', django выдает мне Type Error

Нормальные родительские комментарии работают правильно

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

моей базой данных является mySQL.

Ошибка:

in _calculate_inter_tree_move_values
    space_target = target_right - 1
                   ~~~~~~~~~~~~~^~~
TypeError: unsupported operand type(s) for -: 'NoneType' and 'int'

my models.py:

from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from mptt.models import MPTTModel, TreeForeignKey

STATUS = (
    (0,"Draft"),
    (1,"Publish")
)

class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey(User, on_delete= models.CASCADE, related_name='blog_posts')
    updated_on = models.DateTimeField(auto_now=True)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)

    class Meta:
        ordering = ['-created_on']

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('post_detail',args=[self.slug])


class Comment(MPTTModel):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
    name = models.CharField(max_length=80)
    email = models.EmailField()
    body = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    active = models.BooleanField(default=False) 
    parent=TreeForeignKey('self', null=True, blank=True, on_delete=models.CASCADE, related_name='children')

    class MPTTMeta:
        order_insertion_by = ['created_on',]

    def __str__(self):
        return 'Comment {} by {}'.format(self.body, self.name)
    
    #just for the threaded comments
    def get_comments(self):
        return Comment.objects.filter(parent=self).filter(active=True)

views.py:

from django.shortcuts import render, get_object_or_404, redirect, HttpResponseRedirect
from django.views import generic
#from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
#from django.template import loader
from .models import Post, Comment
from .forms import CommentForm


class PostList(generic.ListView):
    queryset = Post.objects.filter(status=1).order_by('-created_on')
    template_name = 'index.html'
    paginate_by = 3

#class PostDetail(generic.DetailView):
#    model = Post
#    template_name = 'post_detail.html'

class AboutMe(generic.TemplateView):
    template_name = 'about_me.html'

class Contact(generic.TemplateView):
    template_name = 'contact.html'

class Impressum(generic.TemplateView):
    template_name = 'impressum.html'

class StaticContent(generic.TemplateView):
    template_name = 'static_html_content.html'

class SideBar(generic.TemplateView):
    template_name = 'sidebar.html'

#class PostDetail(generic.DetailView):
#    model = Post
#    context_object_name = "post"
#    template_name = "post_detail.hhml"

def post_detail(request, post):
    template_name = 'post_detail.html'
    post = get_object_or_404(Post, slug=post, status=1)
    comments = post.comments.filter(active=True)

    new_comment = None
    #comment posted
    if request.method == 'POST':
        comment_form = CommentForm(request.POST)
        if comment_form.is_valid():

            # Create comment object but dont save to database yet
            new_comment = comment_form.save(commit=False)
            # Assign thecurrent post to the comment
            new_comment.post = post
            #save the comment to the database
            new_comment.save()
            #redirect to the same page and focus on that comment
            return HttpResponseRedirect('/' + post.slug)
            #return redirect(post.get_absolute_url()+'#'+str(new_comment.id))
    else:
        comment_form = CommentForm()

    return render(request, template_name, {'post': post, 'comments': comments, 'new_comment': new_comment, 'comment_form': comment_form})


def reply_page(request):
    if request.method == 'POST':
        form = CommentForm(request.POST)

        if form.is_valid():
            post_id = request.POST.get('post_id')
            parent_id = request.POST.get('parent')
            post_url = request.POST.get('post_url')

            print(post_id)
            print(parent_id)
            print(post_url)
            print('was here reply!')

            reply = form.save(commit=False)

            reply.post = Post(id=post_id)
            reply.parent = Comment(id=parent_id)
            reply.save()

            return redirect(post_url+'#'+str(reply.id))
    
    return redirect('/')

forms.py:

from .models import Comment
from django import forms
from mptt.forms import TreeNodeChoiceField

class CommentForm(forms.ModelForm):
    parent = TreeNodeChoiceField(queryset=Comment.objects.all())

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.fields['parent'].widget.attrs.update(
            {'class': 'd-none'})
        self.fields['parent'].label = ''
        self.fields['parent'].required = False


    class Meta():
        model = Comment
        fields = ('name', 'parent', 'email', 'body')

        widgets = {
            'name': forms.TextInput(attrs={'class': 'col-sm-12'}),
            'email': forms.TextInput(attrs={'class': 'col-sm-12'}),
            'body': forms.Textarea(attrs={'class': 'form-control'}),
        }

    def save(self, *args, **kwargs):
        Comment.objects.rebuild()
        return super(CommentForm, self).save(*args, **kwargs)

post_details.html:

Я пытался изменить значения в полях формы в post_details.html на node.parent.id. но, похоже, ничего не происходит.

Также я попытался изменить тип данных parent_id, чтобы посмотреть, произойдет ли что-нибудь. Но поскольку он работает в этом Opperant-Error, я думаю, что это может быть проблема с сохранением в базу данных mySQL...

Ок... Теперь я нашел ответ. В файле views.py я отредактировал следующие строки:

parent_id = request.POST.get('parent')

и заменить 'parent' на 'commend_id'

parent_id = request.POST.get('comment_id')

В post_detail.html я изменил форму:

<input type="hidden" name="parent" value="{{comment.id}}">

до...

<input type="hidden" name="comment_id" value="{{node.id}}">

Теперь он работает как ожидалось! УРА!

Вернуться на верх