使用基于 class 的视图 django 过滤选项

Filter Option with class based view django

我需要在我的帖子中按 topic/category 进行过滤;但我认为使用基于 class 的视图很难做到这一点。

我有:(有效)

class Post(models.Model):
    class Topic(models.TextChoices):
        DEV = 'DEVELOPMENT', ('Development')
        LIFE = 'LIFE', ('Life')
        OTHER = 'OTHER', ('Other')
        __empty__ = ('-Unknown-')

    topic = models.CharField(max_length=15, choices=Topic.choices, default=Topic.__empty__)

def filter_view(request, topic):
    posts = Post.objects.filter(
        topic__contains=topic
    ).order_by('-pub_date')
    return render(request, 'blog/posts.html', {'posts': posts})
urlpatterns = [
    path('', IndexView.as_view(), name='blog'),
    path('posts/', PostsView.as_view(), name='posts'),
    path('posts/<slug:slug>-<int:id>/', PostDetailView.as_view(), name='post_detail'),
    path('posts/topic=<topic>/', filter_view, name='topic'),
]
<div class="my-3">
    <span class="bg-white rounded-pill px-2 text-muted">Filter by:</span>
    <a href="{% url 'blog:topic' 'Development' %}" metho="GET" class="px-2 bg-success bg-opacity-10 text-decoration-none text-success px2">Development</a>
    <a href="{% url 'blog:topic' 'Life' %}" class="px-2 bg-success bg-opacity-10 text-decoration-none text-success px-2">Life</a>
    <a href="{% url 'blog:topic' 'Other' %}" class="px-2 bg-success bg-opacity-10 text-decoration-none text-success px-2">Other</a>
</div>

**但我想使用基于 class 的视图 **

lass TopicView(generic.ListView):
    template_name = 'blog/posts.html'
    context_object_name = 'posts'

    def get_queryset(self):
        topic = self.request.GET.get('topic')
        return posts = Post.objects.filter(
            topic__contains=topic
        ).order_by('-pub_date')
urlpatterns = [
    # Other code
    path('posts/topic=<topic>/', TopicView.as_view(), name='topic'),
]

错误:

Internal Server Error: /blog/posts/topic=Development/
Traceback (most recent call last):
  File "D:\projects\Python3\python3.10.1\Django\venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "D:\projects\Python3\python3.10.1\Django\venv\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "D:\projects\Python3\python3.10.1\Django\venv\lib\site-packages\django\views\generic\base.py", line 69, in view
    return self.dispatch(request, *args, **kwargs)
  File "D:\projects\Python3\python3.10.1\Django\venv\lib\site-packages\django\views\generic\base.py", line 101, in dispatch
    return handler(request, *args, **kwargs)
  File "D:\projects\Python3\python3.10.1\Django\venv\lib\site-packages\django\views\generic\list.py", line 142, in get
    self.object_list = self.get_queryset()
  File "D:\projects\Python3\python3.10.1\Django\website\blog\views.py", line 36, in get_queryset
    posts = Post.objects.filter(
  File "D:\projects\Python3\python3.10.1\Django\venv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "D:\projects\Python3\python3.10.1\Django\venv\lib\site-packages\django\db\models\query.py", line 974, in filter
    return self._filter_or_exclude(False, args, kwargs)
  File "D:\projects\Python3\python3.10.1\Django\venv\lib\site-packages\django\db\models\query.py", line 992, in _filter_or_exclude
    clone._filter_or_exclude_inplace(negate, args, kwargs)
  File "D:\projects\Python3\python3.10.1\Django\venv\lib\site-packages\django\db\models\query.py", line 999, in _filter_or_exclude_inplace
    self._query.add_q(Q(*args, **kwargs))
  File "D:\projects\Python3\python3.10.1\Django\venv\lib\site-packages\django\db\models\sql\query.py", line 1375, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "D:\projects\Python3\python3.10.1\Django\venv\lib\site-packages\django\db\models\sql\query.py", line 1396, in _add_q
    child_clause, needed_inner = self.build_filter(
  File "D:\projects\Python3\python3.10.1\Django\venv\lib\site-packages\django\db\models\sql\query.py", line 1329, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "D:\projects\Python3\python3.10.1\Django\venv\lib\site-packages\django\db\models\sql\query.py", line 1185, in build_lookup
    raise ValueError("Cannot use None as a query value")
ValueError: Cannot use None as a query value

我认为代码找不到主题名称所以无法搜索;我可以解决这个问题吗?或者我应该这样更好吗?

您没有使用 self.request.GET 获得 URL 参数,但是使用 self.kwargs,所以:

class TopicView(generic.ListView):
    template_name = 'blog/posts.html'
    context_object_name = 'posts'

    def get_queryset(self):
        return Post.objects.filter(
            <strong>topic__contains=self.kwargs['topic']</strong>
        ).order_by('-pub_date')