【问题标题】:Include JSON from Django Rest Framework in an HTML template在 HTML 模板中包含来自 Django Rest Framework 的 JSON
【发布时间】:2015-06-27 17:59:44
【问题描述】:

我正在尝试做一些非常简单的事情,但还没有找到方法。

我有一个模型和一个端点,它返回一个 JSON 数组,用 Django Rest Framework 表示该模型的实例。我想在 HTML 模板中包含 JSON(用于 SEO 和快速初始数据加载)。类似的东西

<script>
    var data = {% json_from_django_rest_framework "mymodel" %};
</script>

有没有简单的方法来做到这一点?我应该换一种方式吗?

【问题讨论】:

  • 你想如何渲染/创建这个模板?显然,DRF 端点将为您提供一些数据(在本例中为 JSON)。要在服务器上静态呈现该 JSON,您可以创建一个提供模板的普通 Django 视图。在该视图中,您可以从 DRF 端点请求数据。我想稍后前端的一些 Javascript 会控制你的 web 应用程序,这就是为什么你首先需要 REST API?
  • 是的,我可以在视图中用 python 序列化 JSON。我希望有一种更直接的方法可以直接在模板中执行此操作。事实上,稍后 javascript 会向 REST 端点发出进一步的请求。
  • 您的目标是完全避免额外的视图,还是只是为了避免必须创建 DRF 端点已经在此额外视图中提供的相同输出?在后一种情况下,您可以使用 Django 的 resolve 助手在您的视图中重用来自 DRF 的 JSON 输出,从而使其保持干燥。 (我可以提供一个例子)
  • 后者。是的,举个例子就好了。

标签: json django django-templates django-rest-framework


【解决方案1】:

执行此操作的另一种方法是绕过渲染视图。

在你的views.py中;

class FooDetailView(DetailView):
    model = Foo
    template_name = 'foo/detail.html'

    def get_context_data(self, **kwargs):
        bars = []
        for bar in self.object.bars.all():
            bars.append(BarSerializer(bar).data)

        kwargs['bars'] = JSONRenderer().render(bars)

        return super(FooDetailView, self).get_context_data(**kwargs)

在你的模板中;

<script>
    var bars = {{ bars|safe }};
</script>  

不言而喻,您应该注意这种方法的潜在性能问题,即.. 也许最好分页bars

【讨论】:

  • 我更喜欢这个答案,因为如果您不打算通过视图集公开数据,它不需要您创建序列化程序的视图
【解决方案2】:

正如 cmets 中所讨论的,这里是一个示例,说明如何使用 Django 的 resolve 函数在普通 Django 视图中重用来自 api 端点的结果。

views.py

import json
from django.core.urlresolvers import resolve
from django.views.generic.base import View    

class FooView(View):
    def get(self, request):
        # optional stuff in your view...

        ##
        # Resolving another Django view programmatically
        ##
        rev = '/path/to/api/endpoint/'  # or use reverse()
        view, vargs, vkwargs = resolve(rev)
        vkwargs['request'] = request
        res = view(*vargs, **vkwargs)

        c = Context({
            'data': json.dumps(res.data)
        })

        # Now the JSON serialized result from the API endpoint
        # will be available in the template variable data.
        return render(request, 'my-app/my-template.html', c)

my-template.html

<script>
    var data = {{ data }};
</script>

注意 1: 与其硬编码 rev = '/path/to/api/endpoint/' 中的路径,不如使用reverse() url,但我将其删除以将其作为错误来源删除。如果你正朝着这个方向前进,这里是 DRF 提供的默认 url 名称的a list

注意 2: sn-p 将受益于异常处理,例如确保 res 返回 200、具有 data 属性等。

【讨论】:

    猜你喜欢
    • 2020-12-25
    • 2021-04-08
    • 2016-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-19
    • 2016-12-29
    • 2016-11-27
    相关资源
    最近更新 更多