【问题标题】:how to properly use {% include %} tag to render a template (like partials) in django?如何正确使用 {% include %} 标签在 django 中呈现模板(如部分)?
【发布时间】:2016-03-31 05:00:58
【问题描述】:

我在左侧有一个显示我的子类别的链接列表。我想要发生的是当用户点击一个子类别时,它会将数据/内容呈现到右侧。

我使用的是基于类的视图,所以我的初始页面是一个显示所有子类别对象的 ListView (subcategory_list.html)。

所以每个 Subcategory 对象都有一个 DetailView (subcategory_detail.html)。

我想根据单击的子类别链接显示 DetailView 模板(在同一页面上)。

如果我理解正确,我将不得不使用 {% include %} 标签和一些 AJAX ???

如何阻止浏览器转到新 URL??

谢谢!

views.py

class SubcategoryListView(ListView):
model = Subcategory
template_name = 'categories/subcategory_list.html'

class SubcategoryDetailView(DetailView):
model = Subcategory
template_name = 'categories/subcategory_detail.html'

def get_context_data(self, **kwargs):
    context = super(SubcategoryDetailView, self).get_context_data(**kwargs)
    context['tasks'] = Task.objects.filter(subcategory=self.object)
    context['contractors'] = ContractorProfile.objects.filter(subcategory=self.object)
    return context

subcategory_list.html

{% extends 'base.html' %}

{% block content %}
<div class="container">
    <div class="col-md-3">
        {% for subcategory in object_list %}
            <p><a href="{% url 'categories:subcategory' subcategory.id %}">{{ subcategory.title }}</a></p>

        {% endfor %}
    </div>
    <div class="col-md-9">
        {% include 'categories/subcategory_detail.html' %}
    </div>
</div>

{% endblock %}

subcategory_detail.html

{% extends 'base.html' %}

{% block content %}
<div class="container">
    <h3>Subcategory: {{ object.title }}</h3>

    {% if user.is_authenticated%}
        <div class="row">
            {% for task in tasks %}
            <div class="thumbnail col-md-3">
                <img src="#" class="img-circle" />
                <div class="caption">
                    <p>Title: {{ task.title }}</p>
                    <p>Description: {{ task.description }}</p>
                    <p>Special Instructions: {{ task.special_instructions }}</p>
                    <p>Posted by: {{ task.user.username }}</p>
                </div>
            </div>
            {% cycle '' '' '' '</div><div class="row">' %}
            {% endfor %}

    {% endif %}
    </div>

</div>
<div class="container">
    <h3>Contractors Available:</h3>
    <div class="row">
        {% for contractor in contractors %}
        <div class="thumbnail col-md-3">
            <img src="#" class="img-circle" />
            <div class="caption">
                <p>Name: {{ contractor.contractor.username }}</p>
                <p>Rating: {{ contractor.rating }}</p>
                {% if contractor.contractor.is_online == True %}
                    <span class="glyphicon glyphicon-fire"></span> <span>Online Now</span>
                {% endif %}
            </div>
        </div>
        {% cycle '' '' '' '</div><div class="row">' %}
        {% endfor %}
</div>



{% endblock %}

urls.py

urlpatterns = [
    url(r'^subcategories/$', views.SubcategoryListView.as_view(), name='subcategories'),
    url(r'^subcategories/(?P<pk>\d+)/$', views.SubcategoryDetailView.as_view(), name='subcategory'),
]

【问题讨论】:

  • 如果没有 JavaScript 或重新加载页面,就无法做到这一点。如果你想要第一个解决方案,你应该提供描述你迄今为止尝试过的代码:你不能指望任何人为你编写整个 JavaScript 行为。
  • 不查找整个代码。只是朝着正确的方向轻推。
  • 是的。所以我可以将它设置为所有链接都获得#id,然后传递一个唯一的数据属性。然后将 {% include 'template_name.html' %} 标记附加到特定的
    。但我的担忧/问题是系统在加载哪个 DetailView 之间会有什么不同(即 Subcategory1 与 Subcategory2 DetailView)?
  • 我的回答只涉及它的 JS 方面。这是 Django 的责任:让我更新答案以涵盖这个问题。
  • 其实这应该不是问题。 self.object 应该已经包含 Subcategory 对象。尝试打开“youwebsite/subcategories/0”(考虑到数据库中至少有一个 Subcategory 对象)。它呈现正确的吗?如果是,您的最后一个问题已经解决。

标签: python ajax django django-templates django-views


【解决方案1】:

所有不是通过刷新页面而是需要服务器内容来完成的,都需要使用 JavaScript。在这种情况下,您希望将 HTML 内容(由 Django 提供)注入到您的页面中。

我将在这里使用 jQuery。

首先,您要识别需要注入内容的 div(以便 JavaScript 能够引用它)和 div。

另外,删除{% include %} 标签(或者让标签呈现您想要在用户加载页面时呈现的内容)。

(在subcategory_list.html(应该改名为subcategory.html)):

<div class="container subcategory_list">
    <div class="col-md-3">
        {% for subcategory in object_list %}
            <p><a href="{% url 'categories:subcategory' subcategory.id %}">{{ subcategory.title }}</a></p>

        {% endfor %}
    </div>
    <div class="col-md-9" id="subcategory_detail">
        {% include 'categories/subcategory_detail.html' %}
    </div>
</div>

然后你需要告诉a href不要加载页面,而是让ajax调用发生。

<script type="text/javascript">
    $(function() { // shortcut for onDocumentReady

        // When you click an "a" tag who is child of an item with class "subcategory_list"…
        $('.subcategory_list>a').click(function() {

            var href = $(this).attr('href');

            // Use this if you want to add a loading gif or something similar
            // $('#subcategory_detail').html(my_cool_loading_gif_html)

            $.get(href, {
                success: function(response) {
                    // If the ajax call is successful, take the response and inject in div with id "subcategory_detail"
                    $('#subcategory_detail').html(response)
                },
                error: function(response) {
                    // Handle ajax errors here
                }
            })
            return false;
        });

    });
</script>

【讨论】:

  • 嗯..它只是将我带到子类别详细信息页面,即使使用'return false;'最后
  • 代码正在运行:jsfiddle.net/Saturnix/w7L821vo/3 你检查过你的 JS 控制台了吗?您是否尝试过使用 console.log() 进行调试? jQuery 是否正确包含?
  • 好的。 return false 现在正在工作。我能够在 $.get{success:} 中获得“href”值。但是“响应”=未定义。这意味着它实际上并没有从特定的 url 获取数据,对吗?
  • 我必须将数据序列化为 JSON 吗?
  • 绝对不是:您应该返回 HTML 代码,而不是 JSON。我不明白为什么响应对象是空的。能不能在success函数里放一个console.log(response),看看得到了什么?
猜你喜欢
相关资源
最近更新 更多
热门标签