【问题标题】:NoReverseMatch at /post/1/log/ Reverse for 'log-create' with keyword arguments '{'post_id': ''}' not foundNoReverseMatch at /post/1/log/ Reverse for 'log-create' with keyword arguments '{'post_id': ''}' not found
【发布时间】:2020-02-23 02:46:18
【问题描述】:

我有一个包含一大堆帖子的帖子模型。我还有一个日志模型,它具有 Post 模型的外键字段。本质上,Log 模型在 Post 模型(基本上是 Post cmets)中存储 Posts 的日志条目。一切都很顺利。我一直在为我的帖子模型使用 CBV,并使用 CBV 来列出我的日志条目。然后,我添加了一个链接,使用以下锚标记将我重定向到 Log CreateView:

<a class="btn" href="{% url 'log-create' post_id=logs.post_id %}">Add Entry</a>

当 NoReverse 错误开始发生时。当我将 log.post_id 更改为 1 时,页面加载正确。这让我相信 log.post_id 没有返回任何值。我的另一个想法是,因为这个锚标记在 LogListView 上有多个日志条目,所以它不知道要使用哪个 post_id。但是我在这个视图上使用了 get_queryset 函数来确保只返回与单个帖子相关的日志。在我看来,log.post_id 应该可以工作。

我的模型是:

class Post(models.Model):
    title = models.CharField(max_length=100, blank=True)
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    overview = models.TextField(blank=True)

    def get_absolute_url(self):
        return reverse('post-detail', kwargs={'pk': self.id})

    def __str__(self):
        return self.title

class Log(models.Model):
    post = models.ForeignKey(Post, default=None, on_delete=models.CASCADE)
    log_entry = models.TextField(max_length=500, blank=True)
    log_author = models.ForeignKey(User, on_delete=models.CASCADE)
    date_posted = models.DateTimeField(default=timezone.now)

我的观点:

from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView, DetailView, CreateView
from .models import Post, Log
from django.http import HttpResponseRedirect
from django.contrib.auth.mixins import LoginRequiredMixin

class LogListView(ListView):
    model = Log
    template_name = 'blog/log_entries.html'
    context_object_name = 'logs'
    ordering = ['-date_posted']

    def get_queryset(self):
        self.post = get_object_or_404(Post, log=self.kwargs['pk'])
        return Log.objects.filter(post=self.post)

    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super(LogListView, self).get_context_data(**kwargs)
        # Add in a QuerySet of all images related to post
        context['post'] = Post.objects.all()
        return context

class LogCreateView(LoginRequiredMixin, CreateView):
    model = Log
    fields = [
            'log_entry'
            ]

    def form_valid(self, form):
        form.instance.log_author = self.request.user
        post = Post.objects.get(pk=self.kwargs['post_id'])
        return super().form_valid(form)

我的 urls.py


from django.urls import path, include
from . import views 
from .views import LogListView, LogCreateView

urlpatterns = [
    path('', PostListView.as_view(), name='blog-home'),
    path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'),
    path('post/new/', PostCreateView.as_view(), name='post-create'),
    path('post/<int:pk>/log/', LogListView.as_view(), name='log-list'),
    path('post/<int:post_id>/log/new/', LogCreateView.as_view(), name='log-create'),
]

最后,我的模板:

{% extends "blog/base.html"%}
{% block body_class %} home-section {% endblock %}
{% block content %}
  <div class="container">
    <h2>Log Entries</h2>
      {% for log in logs %}
      <div class="row">
        <article class="content-section">
            <div class="article-metadata log-metadata">
              <a class="mr-2" href="{% url 'profile' user=log.log_author %}">{{ log.log_author }}</a>
              <small class="text-muted">{{ log.date_posted|date:"d F Y" }}</small>
              {% if request.user.is_authenticated and request.user == log.log_author %}
                <a href="#"><ion-icon name="trash"></ion-icon></a>
              {% endif %}
            </div>
            <p class="">{{ log.log_entry }}</p>
        </article>
        </div>
      {% endfor %}
      <a class="btn" href="{% url 'log-create' post_id=logs.post_id %}">Add Entry</a>

  </div>
{% endblock content %}

我认为我正确地将参数传递给了 url。从我使 post_id=1 可以看出这一点。但我不确定我是否正确调用它。对此问题的任何帮助将非常感谢。

更新:我在 LogListView 中将 context_object_name 编辑为日志,以减少 for 循环的混乱。本质上,我试图在所有日志条目的底部获取一个锚标记以重定向到添加条目页面。

【问题讨论】:

    标签: python django django-urls django-class-based-views


    【解决方案1】:

    我建议使用第一个元素,仅在有可用对象时才呈现链接:

      </article>
      </div>
      {% if forloop.first %}<a class="btn" href="{% url 'log-create' post_id=log.post.id %}">Add Entry</a>{% endif %}
    {% endfor %}
    

    这个log.post.id表示获取日志对象的post对象的id(外键)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-14
      • 1970-01-01
      • 2016-04-18
      • 1970-01-01
      相关资源
      最近更新 更多