django 模板调用js_将下一个js预呈现的html页面作为Django模板提供

django 模板调用js

I’ve been building a site that uses a React frontend and Django backend, and I’ve finally gotten around to thinking about how to improve the marketing pages (i.e. landing page, etc.). However, some of the well-known problems with using React for a landing page are (1) worse SEO and (2) likely slower page loading times (which also impacts google ranking).

我一直在建立一个使用React前端和Django后端的网站,最后我终于开始思考如何改善营销页面(即目标页面等)。 但是,使用React登陆页面的一些众所周知的问题是(1)SEO较差;(2)页面加载时间可能会变慢(这也会影响Google排名)。

So I wanted to instead pre-render the marketing pages. Two major solutions that are compatible with my React code are Gatsby and Next.js. And after some googling around, it seemed Next.js could do everything Gatsby could do and would be easier to setup. So I chose Next.js.

因此,我想预渲染营销页面。 与我的React代码兼容的两个主要解决方案是GatsbyNext.js。 经过一番探索之后,Next.js似乎可以完成Gatsby可以做的所有事情,并且设置起来也更加容易。 所以我选择了Next.js。

But the real challenge I had was figuring out the relationship between Next.js and my Django backend. In short, I decided to use Next.js to pre-render my marketing pages and serve them as Django templates. Below I’ll show you how I did it.

但是我真正面临的挑战是弄清楚Next.js和Django后端之间的关系。 简而言之,我决定使用Next.js预先渲染我的营销页面并将其用作Django模板。 下面,我将向您展示如何做到这一点。

Caveat: I am definitely not a seasoned software engineer (I am a computational biologist by training), but what I came up with works just fine for me. However, some alternative solutions some people might suggest are: (1) just use wordpress for marketing pages, or (2) decouple the marketing pages from django and instead serve it with Next.js on a subdomain or something. Nonetheless, if you still have any thoughts/criticism, I am more than happy to hear them.

警告:我绝对不是经验丰富的软件工程师(我是受过培训的计算机生物学家),但是我的想法对我来说很好。 但是,某些人可能会建议一些替代解决方案:(1)仅将wordpress用于营销页面,或(2)将营销页面与django分离,然后在子域或其他内容上与Next.js一起使用。 但是,如果您仍然有任何想法/批评,我很乐意听到。

Next.js兼容性 (Next.js compatibility)

The first big hassle was to bring all the React code for my marketing pages into its own Django app and make it compatible with Next.js. While Next.js has some pretty good documentation on how to do this, it was still quite annoying (especially since I did not spend much time learning Next.js in-depth :P).

第一个大麻烦是将我的营销页面的所有React代码都带到自己的Django应用中,并使其与Next.js兼容。 尽管Next.js上有一些很好的文档,但是仍然很烦人(特别是因为我没有花很多时间来深入学习Next.js:P)。

Once I was able to successfully build the pages (via npx next build), Next.js has a command to export the pages to static HTML (via npx next export -o output_folder).

一旦我能够成功构建页面(通过npx npx next build ),Next.js就会有一个命令将页面导出到静态HTML(通过npx next export -o output_folder )。

与Django集成 (Integrating with Django)

Next.js pre-rendered HTML files are small and bare-bones, but they still need some accompanying js and css bundles to render correctly (listed within the <head> section). Here is one example:

Next.js预先渲染HTML文件虽然很小而且很简陋,但是它们仍然需要一些随附的js和css捆绑包才能正确渲染(在<head>部分中列出)。 这是一个例子:

<link as="script" href="/_next/static/chunks/main-5f4f60561676956d0ca5.js"rel="preload"/>

However, when I serve the HTML page as a Django template, it will not be able to find the js/css bundles. Since Django normally looks for static files in the static directory, I needed to add the static template tags so Django knows where to find the js/css files. Like so:

但是,当我将HTML页面用作Django模板时,它将无法找到js / css包。 由于Django通常在静态目录中查找静态文件,因此我需要添加静态模板标签,以便Django知道在哪里可以找到js / css文件。 像这样:

<link as="script" href='{% static "/_next/static/chunks/main-5f4f60561676956d0ca5.js" %}' rel="preload"/>

But since I don’t want to manually make those edits, I wrote a python script to do it for me using BeautifulSoup (which is an HTML parsing library):

但是由于我不想手动进行这些编辑,因此我编写了一个Python脚本来使用BeautifulSoup(这是一个HTML解析库)为我完成此操作:

import argparse
import glob
import osfrom bs4 import BeautifulSoupdef parse_args():
parser = argparse.ArgumentParser()
parser.add_argument(
'-d',
'--dir',
type=str,
required=True) args = parser.parse_args() return args
def search_and_parse(soup, tag): for x in soup.find_all(tag): if x.get('src') and x['src'].startswith('/_next/'):
x['src'] = "{% static \"" + x['src'] + "\" %}" if x.get('href') and x['href'].startswith('/_next/'):
x['href'] = "{% static \"" + x['href'] + "\" %}"
def main(): args = parse_args() for html_file in glob.glob(os.path.join(args.dir, '*html')): soup = BeautifulSoup(open(html_file), 'html.parser')
soup.insert(0, '{% load static %}') # add script to store user info into window on page load
# is a workaround so i don't need redux django_script = BeautifulSoup("<script>window.django = {is_authenticated: \"{{ request.user.is_authenticated }}\" === \"True\" ? true : false, user_plan: \"{{user_plan}}\"};</script>", 'html.parser')
head = soup.find('head')
head.append(django_script) search_and_parse(soup, 'link')
search_and_parse(soup, 'script') fout = open(html_file, 'wb')
fout.write(soup.prettify('utf-8'))
fout.close()
main()

You’ll notice a couple extra things:

您会注意到一些额外的事情:

  1. I added {% load static %} at the top of the HTML file, which Django needs in order for the static files to work correctly.

    我在HTML文件的顶部添加了{% load static %} ,Django需要该文件才能使静态文件正常工作。

  2. I use the template context variables to store some information into the browser’s window object. I need this so I know if the user is logged in and what their payment plan is while they view the marketing pages.

    我使用模板上下文变量将一些信息存储到浏览器的window对象中。 我需要这个,所以我知道用户是否登录以及在查看营销页面时他们的付款计划是什么。

Another important step is actually placing all the js/css bundles within the static folder. Oddly, running npx next export -o static does not work and causes some strange bug. So I instead did this npx next export -o output && mv output static.

另一个重要步骤实际上是将所有js / css捆绑包放在static文件夹中。 奇怪的是,运行npx next export -o static无法正常工作,并且会导致一些奇怪的错误。 所以我代替了npx next export -o output && mv output static

The final step is to actually place the HTML pages within Django’s required template directory. However, instead of directly moving the HTML files from the static folder to the template folder, I created soft links to them. For example, while I am within the template directory, I ran the following ln -s ../static/index.html index.html. The advantage is that I don’t need to commit the pre-rendered HTML files to my git repo, I only need to commit the soft links. In fact, none of the output files from running npx next export are in my git repo, only the React files that produce them are in my git repo.

最后一步是将HTML页面实际放置在Django所需的template目录中。 但是,我没有将HTML文件从static文件夹直接移动到template文件夹,而是创建了指向它们的软链接。 例如,当我在template目录中时,我运行了以下ln -s ../static/index.html index.html 。 好处是我不需要将预渲染HTML文件提交到git repo,而只需提交软链接。 实际上,从运行npx next export的输出文件都不在我的git仓库中,只有生成它们的React文件在我的git仓库中。

Edit: For the above paragraph, I later found that while using links works fine for the local dev environment, I had to actually copy over the HTML files into the template directory to get it to work on AWS-Elastic Beanstalk.

编辑:对于上面的段落,我后来发现,尽管使用链接在本地开发环境中可以正常工作,但我实际上必须将HTML文件复制到模板目录中才能使其在AWS-Elastic Beanstalk上工作。

最后结果 (Final result)

I then combined all the above commands and scripts into one simple build command. Here is what my packages.json scripts section looks like:

然后,我将上述所有命令和脚本组合成一个简单的构建命令。 这是我的packages.json脚本部分的样子:

"scripts": {
"dev": "next dev",
"build": "next build",
"deploy": "rm -rf output static && next export -o output && mv output static && python ../bin/finalize_marketing_build.py -d static",
"start": "next start"
},

翻译自: https://medium.com/@murphy.charlesj/serving-next-js-pre-rendered-html-pages-as-django-templates-d13b8ab3976b

django 模板调用js

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对你的问题,我可以给你一些具体的实现过程和代码示例。 首先,我们假设后端使用 Python,前端使用 jQuery 和 DataTables 插件,以及 Django 框架的视图模板语言。 1. 后端代码 首先,我们需要在后端编写一个 API 接口,用于返回按年龄排序后的用户数据。这里我们使用 PythonDjango 框架来实现。 ```python # views.py from django.http import JsonResponse from app.models import User def sort_users_by_age(request): # 获取用户数据并按年龄排序 users = User.objects.all().order_by('age') # 将用户数据转换为 JSON 格式并返回 data = [{'id': user.id, 'name': user.name, 'age': user.age} for user in users] return JsonResponse(data, safe=False) ``` 上述代码中,我们首先从数据库中获取用户数据,并按照年龄排序,然后将数据转换为 JSON 格式并返回。注意,这里我们使用了 DjangoJsonResponse 类来返回 JSON 格式的数据。 2. 前端代码 接下来,我们需要在前端使用 jQuery 和 DataTables 插件来实现分页功能。 ```html <!-- index.html --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>User List</title> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css"> </head> <body> <table id="user-table" class="display" style="width:100%"> <thead> <tr> <th>ID</th> <th>Name</th> <th>Age</th> </tr> </thead> <tbody> </tbody> </table> <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script> <script> $(document).ready(function() { $('#user-table').DataTable({ 'processing': true, 'serverSide': true, 'ajax': { 'url': '/sort_users_by_age/', 'type': 'GET' }, 'columns': [ {'data': 'id'}, {'data': 'name'}, {'data': 'age'} ] }); }); </script> </body> </html> ``` 上述代码中,我们首先在 HTML 中定义一个 table 容器,用于显示用户数据。然后,我们引入 jQuery 和 DataTables 插件的 CSS 和 JavaScript 文件,并在 JavaScript 中使用 DataTables 插件来实现分页功能。 具体来说,我们在 DataTables 的初始化参数中指定了以下几个选项: - processing:开启 DataTables 内置的加载动画; - serverSide:启用服务器端模式,即将数据从后端加载到前端; - ajax:指定获取数据的 URL 和请求方式; - columns:指定要显示的列和数据。 注意,这里的 URL 是后端提供的 API 接口,我们在 JavaScript 中直接调用该接口来获取数据。 3. Django 视图模板代码 最后,我们需要在 Django 的视图模板中渲染上述 HTML 文件。 ```python # views.py from django.shortcuts import render def index(request): return render(request, 'index.html') ``` 上述代码中,我们使用 Django 的 render 函数来渲染 index.html 文件,并将其返回给用户。 至此,我们就完成了用户数据按年龄排序并分页显示的功能。当用户访问 index 页面时,前端会调用后端的 sort_users_by_age 接口来获取用户数据,并将数据显示到 table 容器中。用户还可以通过 DataTables 插件提供的分页功能来浏览数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值