Добавление к комментариям к записи: Страница не найдена (404) - PullRequest
0 голосов
/ 30 апреля 2018

Привет Djangonauts Я новичок в Django, пожалуйста, прости меня, если у меня есть глупые ошибки в моем коде, и в настоящее время я пытаюсь добавить комментарии к моей модели поста

ниже мои models.py

class Post(models.Model):
    user = models.ForeignKey(User, related_name='posts')
    title = models.CharField(max_length=250, unique=True)
    slug = models.SlugField(allow_unicode=True, unique=True)
    message = models.TextField()

    def get_absolute_url(self):
        return reverse('posts:single', kwargs={'username': self.user.username, 'slug': self.slug}) 

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        super().save(*args, **kwargs)


class Comment(models.Model):
    post = models.ForeignKey(Post, related_name='comments')
    author = models.ForeignKey(User, related_name='comments')
    text = models.TextField()

    def get_absolute_url(self):
        return reverse('posts:single', kwargs={'username': self.post.user.username,
                                               'slug': self.post.slug})

views.py 1-я попытка

@login_required
def add_comment_to_post(request, slug):
    post = get_object_or_404(Post, slug=slug)
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = post
            comment.author = request.user
            comment.save()
            return redirect('posts:single', username=comment.author.username, slug=post.slug)

    else:
        form = CommentForm()
        return render(request, 'posts/comment_form.html', {'form': form})


@login_required
def remove_comment(request, pk):
    comment = get_object_or_404(Comment, pk=pk)
    comment.author = request.user
    post_slug = comment.post.slug
    comment.delete()
    return redirect('posts:single', username=request.user.username, slug=post_slug)

urls.py

url(r'^(?P<slug>[-\w]+)/add_comment/$', views.CommentCreate.as_view(), name='add_comment'),

Также у меня есть URL для FBV ниже, они оба дают мне ту же ошибку

url(r'^(?P<slug>[-\w]+)/add_comment/$', views.add_comment_to_post, name='add_comment'),
url(r'^(?P<pk>\d+)/remove_comment/$', views.remove_comment, name='remove_comment'),

Views.py 2-я попытка

class CommentCreate(LoginRequiredMixin, CreateView):
    model = Comment
    fields = ('text',)
    form_class = 'posts/comment_form.html'

    def form_valid(self, form, *args, **kwargs):
        self.object = form.save(commit=False)
        self.object.user = self.request.user
        slug = self.kwargs('slug')
        print(slug)
        self.object.post = get_object_or_404(Post, slug=slug)
        self.object.save()
        return super().form_valid(form)

views.py 3-я попытка

@login_required
def add_comment_to_post(request, slug):
    print(slug)
    post = get_object_or_404(Post, slug=slug)
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = post
            comment.author = request.user
            comment.save()
            return redirect('posts:single', username=comment.author.username, slug=post.slug)

    else:
        form = CommentForm()
        return render(request, 'posts/comment_form.html', {'form': form})

также изменил URL-адреса на

url(r'^add_comment/(?P<slug>[\w-]+)/$', views.add_comment_to_post, name='add_comment'),

ниже - вид PostDetail и URL , они отлично работают

class PostDetail(SelectRelatedMixin, DetailView):
    model = Post
    select_related = ('user', 'group')

    def get_queryset(self):
        queryset = super().get_queryset()
        return queryset.filter(user__username__iexact=self.kwargs.get('username'))   
   #below is the url
 url(r'^(?P<username>[-\w]+)/(?P<slug>[-\w]+)/$', views.PostDetail.as_view(), name='single'),

Я получаю такое же сообщение об ошибке , как показано ниже, во всех 3 видах, а также с измененным URL

Page not found (404)
Request Method: GET
Request URL:    http://127.0.0.1:8000/posts/...
Raised by:  posts.views.PostDetail

enter image description here

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Yess !!! понял. У меня на голове несколько повязок и несколько трещин на стене, но я наконец-то понял. Большое спасибо @Bulva за то, что он направил меня в правильном направлении

urls.py должно быть

    url(r'^(?P<username>[-\w]+)/(?P<slug>[-\w]+)/add_comment/$', views.CommentCreate.as_view(), name='add_comment'),

Так как нам нужно как имя пользователя, который публикует комментарий, так и пост, где комментарий должен быть опубликован. Приведенный выше URL имеет как

Файл views.py должен быть таким, как показано ниже

class CommentCreate(LoginRequiredMixin, CreateView):
    model = Comment
    form_class = CommentForm #In the second attempt above I used a template name. which is incorrect we should either use a formclass from forms.py or use "fields = text" 

    def form_valid(self, form, *args, **kwargs):
        self.object = form.save(commit=False)
        self.object.author = self.request.user #I used self.object.user instead of self.object.author. since the models call the "user" as "author". I changed this  
        slug = self.kwargs.get('slug') #I added the .get without which you get a "'dict' object is not callable" error 
        print(slug)
        self.object.post = get_object_or_404(Post, slug=slug)
        self.object.save()
        return super().form_valid(form)

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

<a class="btn btn-primary comment_button" href="{% url 'posts:add_comment' username=post.user.username slug=post.slug %}">Add Comment</a>
0 голосов
/ 30 апреля 2018

Так что я ожидаю, что у вас есть urls.py в ваших проектах, где вы включили urls.py для своего приложения (возможно, с именами постов). Проект urls.py, вероятно, будет выглядеть примерно так:

(r'^posts/', include('project.posts.urls'))

Тогда в вашем приложении urls.py у вас есть то, что вы мне отправили:

url(r'^(?P<slug>[-\w]+)/add_comment/$', views.add_comment_to_post, name='add_comment'),
url(r'^(?P<pk>\d+)/remove_comment/$', views.remove_comment, name='remove_comment'),

Я лично это изменил на версию, где slug и первичный ключ будут в конце URL, как это:

url(r'^add_comment/(?P<slug>[-\w]+)/$', views.add_comment_to_post, name='add_comment')
url(r'^remove_comment/(?P<pk>\d+)/$', views.remove_comment, name='remove_comment'),

Тогда ваш URL для добавления нового комментария будет выглядеть как http://127.0.0.1:8000/posts/add_comment/how-to-be-a-good-developer/. Последняя часть URL - это ваш слаг, и у вас должна быть запись с этим слагом в вашей базе данных, потому что если вы используете функцию get_object_or_404, и у любого из ваших постов не будет отправленного слага, вы получите 404.

Как очень легко отладить ваш код в Django

Вы, вероятно, запускаете свой проект Django из консоли (командной строки) с помощью команды python manage.py runserver. В этой консоли работает небольшой сервер разработки (очень похожий на другие серверы приложений, которые вы, вероятно, знаете). Если вы добавите оператор print() в свой код, то вывод будет отправлен на стандартный вывод (в данном случае на вашу консоль, где вы запустили сервер разработки). Поэтому, если вы отправляете запрос на хороший URL, вы можете добавить операторы печати, чтобы легко отладить проблему. Попробуйте что-то вроде этого:

@login_required
def add_comment_to_post(request, slug):
    print('I am here in your view')
    print('This is my slug: {}'.format(slug))
    post = get_object_or_404(Post, slug=slug)
    print('This is my post: {}'.format(post))
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = post
            comment.author = request.user
            comment.save()
            return redirect('posts:single', username=comment.author.username, slug=post.slug)

    else:
        form = CommentForm()
        return render(request, 'posts/comment_form.html', {'form': form})

Теперь, если вы увидите в консоли I am here in your view, запрос Post был успешно разрешен, и представление было запущено. В это время вы знаете, что ваши urls.py хороши.

Если вы увидите сообщение This is my slug: {your slug from url}, вы можете проверить значение слага и проверить, есть ли в вашей базе данных сообщение с этим слагом.

Последнее, что нужно проверить. Если вы увидите в консоли This is my post: {post object}, вы знаете, что Django выбрал правильный пост, и проблема в следующем коде представления (чего я не ожидаю). Если вы увидите объект «Нет», «404» или какую-либо ошибку в вашей консоли, у вас, вероятно, нет сообщения с тем слагом, который вы отправили в своем URL в базе данных.

Если у вас возникнут вопросы или вы захотите обсудить некоторые выводы в консоли, вы можете написать комментарий: -)

...