如何在django中的分层URL中传递外键?

时间:2018-04-26 14:09:37

标签: html django

我的Django App中有一个层次结构。我想实现以下目标:

  1. 首先展示几个主板
  2. 然后,如果用户点击一块板,我想显示板内的所有主题。
  3. 现在的问题是我在Topic模型中声明了一个外键,但现在可以从每个主板调用该主题,而不仅仅是从我指定的主板中调用。

    这是我的模特:

    from django.db import models
    from django.contrib.auth.models import User
    from mptt.models import TreeForeignKey
    
    # overview over all topics
    class Board(models.Model):
        name = models.CharField(max_length=30, unique=True)
        description = models.CharField(max_length=100)
    
        def __str__(self):
            return self.name
    
    # topics withing the boards
    class Topic(models.Model):
        board = TreeForeignKey(Board, on_delete=models.CASCADE, related_name='Topic')
        subject = models.CharField(max_length=255, unique=True)
        last_updated = models.DateTimeField(auto_now_add=True) # auto_now_add sets current date+time when created
        starter = models.ForeignKey(User, on_delete=models.CASCADE, related_name='Topic')
    
        def __str__(self):
            return self.subject
    

    然后是观点:

    from .models import Board, Topic
    
    class BoardsView(generic.ListView):
        template_name = 'dbconnect/board.html'
        context_object_name = 'board_list'
    
        def get_queryset(self):
            """ Return all boards."""
            return Board.objects.all()
    
    
    class TopicView(generic.ListView):
        model = Topic
        template_name = 'dbconnect/topic.html'
        context_object_name = 'topic_list'
    
        def get_queryset(self):
            """Return all topics."""
            return Topic.objects.all()
    

    board.html工作正常,因为网址中没有第二级:

    <div style = "text-align: left; margin-left: 10%; margin-right: 10%">
    <div style = "display: inline-block; text-align: left;">
        {% if board_list %}
            <ul>
            {% for board in board_list %}
                <li><a href="{% url 'topic' board.id %}">{{ board.name }}</a></li>
            {% endfor %}
            </ul>
        {% else %}
            <p>No boards are available.</p>
        {% endif %}
    </div>
    

    然后是topic.html,现在我迷失了,要通过什么,所以主题是指董事会:

    <div style = "text-align: left; margin-left: 10%; margin-right: 10%">
    <div style = "display: inline-block; text-align: left;">
        {% if topic_list %}
            <ul>
            {% for topic in topic_list %}
                <li><a href="{% url 'level' ***HERE*** topic.id %}">{{ topic.subject }}</a></li>
            {% endfor %}
            </ul>
        {% else %}
            <p>No topics are available.</p>
        {% endif %}
    </div>
    

    在这里你可以看到我的网址:

    app_name = 'dbconnect'
    urlpatterns = [
        path('', views.BoardsView.as_view(), name = 'board'),
        path('<int:topic>/', views.TopicView.as_view(), name='topic'),
        path('<int:topic>/<int:level>/', views.LevelView.as_view(), name='level')]
    

    如何在每个主板内显示限制主题列表?

1 个答案:

答案 0 :(得分:0)

网址

如果我正确理解您的问题,您可能应该调整您的网址以适应您描述的情况:

urlpatterns = [
    ...
    path('<int:board_id>/', views.TopicView.as_view(), name='topic-list'),
    ...
]

第一个网址可以保持不变,但第二个网址会将board_id作为网址参数,而不是topic_id,因为您要显示属于所选主板的主题列表。< / p>

也许可以将该网址从topic重命名为topic-list或类似的内容,以便更清楚地了解它。

现在,在视图中进行过滤:

您可以像这样过滤主题查询集:

class TopicView(generic.ListView):
    model = Topic
    ...

    def get_queryset(self):
        return super().get_queryset().filter(board=self.kwargs['board_id'])

您可以在此处使用super().get_queryset(),因为您已经在课程中定义了model = Topic;请参阅docs

有关类似案例,请参阅this post