wagtail的数据模型和渲染

文章目录

  • 前言
  • 页面数据模型
    • 数据库字段部分
    • 搜索部分
    • 编辑面板
    • 基础面板
    • 结构化面板
    • 父页面/子页面类型规则
    • 页面URLs
      • 自定义页面模型的URL模式
      • 获取页面实例的URL
  • 模板渲染
    • 为页面模型添加模板
    • 模板上下文
    • 自定义模板上下文
    • 更改模板
    • 动态选择模板
    • Ajax 模板
  • 内联模型
    • 在多个页面类型之间重用内联模型
  • 使用页面

前言

Wagtail中的每种页面类型(也称为内容类型)都由Django模型表示。所有页面模型都必须继承自 wagtail.models.Page 类。

正如所有页面类型都是Django模型一样,您可以使用Django提供的任何字段类型。请参阅Django模型字段参考获取可用字段类型的完整列表。此外,Wagtail还提供了 wagtail.fields.RichTextField,该字段提供了一个所见即所得的编辑器,用于编辑富文本内容。

页面数据模型

一个页面的数据模型包括如下基本内容

from django.db import modelsfrom modelcluster.fields import ParentalKeyfrom wagtail.models import Page, Orderable
from wagtail.fields import RichTextField
from wagtail.admin.panels import FieldPanel, MultiFieldPanel, InlinePanel
from wagtail.search import indexclass BlogPage(Page):# 数据库字段body = RichTextField()date = models.DateField("Post date")feed_image = models.ForeignKey('wagtailimages.Image',null=True,blank=True,on_delete=models.SET_NULL,related_name='+')# 搜索索引配置,body和date可被搜索search_fields = Page.search_fields + [index.SearchField('body'),index.FilterField('date'),]# 管理界面编辑面板配置content_panels = Page.content_panels + [FieldPanel('date'),FieldPanel('body'),InlinePanel('related_links', heading="Related links", label="Related link"),]promote_panels = [MultiFieldPanel(Page.promote_panels, "Common page configuration"),FieldPanel('feed_image'),]# 父页面 / 子页面类型规则parent_page_types = ['blog.BlogIndex']subpage_types = []class BlogPageRelatedLink(Orderable):page = ParentalKey(BlogPage, on_delete=models.CASCADE, related_name='related_links')name = models.CharField(max_length=255)url = models.URLField()panels = [FieldPanel('name'),FieldPanel('url'),]

包括以下几个部分

数据库字段部分

每个 Wagtail页面是一个Django数据模型,在数据库中表示一个独立的表。

Wagtail 也提供了一些它自己的类:

RichTextField - For rich text contentStreamField - A block-based content field (see: Freeform page content using StreamField)

对于标签tag Wagtail 完全支持django的标签系统。

搜索部分

搜索字段定义了哪些哪些字段被添加到了搜索索引,是如何被索引的。

   search_fields = Page.search_fields + [index.SearchField('body'),index.FilterField('date'),]

编辑面板

定义了页面的字段是如何通过面板被展示在编辑接口的。

content_panels - 用于内容展示,如,文本等promote_panels - 用于 metadata, 比如 tags, thumbnail image and SEO titlesettings_panels - 用户设置, 比如发布日期

又分为基础的和结构型的

基础面板

编辑数据字段,字段面板会选择合适的wideget来适配这些字段。比如富文本会选择富文本小组件。图片选择小组件选择一个外键指向一个图片模型。

FieldPanelPageChooserPanel

结构化面板

用于结构化字段

MultiFieldPanelInlinePanelFieldRowPanel

父页面/子页面类型规则

这两个属性允许您控制页面类型在站点中的使用位置。它们允许您定义诸如“博客条目只能在博客索引下创建”之类的规则。

parent_page_types 和 subpage_types 都接受模型类或模型名称的列表。模型名称的格式为 app_label.ModelName。如果省略了 app_label,则假定为相同的应用程序。

parent_page_types 限制了可以在此类型下创建哪些页面类型。
subpage_types 限制了可以在此类型下创建哪些页面类型。
默认情况下,任何页面类型都可以在任何页面类型下创建,如果这是期望的行为,则不需要设置这些属性。

将 parent_page_types 设置为空列表是防止特定页面类型在编辑界面中被创建的一种好方法。

页面URLs

检索页面URL的最常见方法是使用 {% pageurl %} 或 {% fullpageurl %} 模板标签。由于它是从模板中调用的,这些标签会自动包含下面提到的优化。

页面模型还包括一些用于覆盖或访问页面URL的低级方法。

自定义页面模型的URL模式

Page.get_url_parts(request) 方法通常不会直接调用,但可以被覆盖以为给定的页面模型定义自定义的URL路由。它应该返回一个元组 (site_id, root_url, page_path),这些由 get_url 和 get_full_url(见下文)用于构建给定类型的页面URL。

在覆盖 get_url_parts() 时,应该接受 *args, **kwargs:

def get_url_parts(self, *args, **kwargs):

并在调用 super 上的 get_url_parts 时传递它们(如果适用),例如:

super().get_url_parts(*args, **kwargs)

虽然您可以仅传递 request 关键字参数,但将所有参数原样传递确保了对这些方法签名的任何未来更改的兼容性。

有关更多信息,请参阅 wagtail.models.Page.get_url_parts()。

获取页面实例的URL

您可以在需要页面URL时调用 Page.get_url(request) 方法。如果它确定页面在当前站点上(通过请求中的主机名),它将默认返回本地URL(不包括协议或域);否则,它将返回包括协议和域的完整URL。在可能的情况下,应包括可选的 request 参数,以启用每个请求的站点级URL信息的缓存,并促进本地URL的生成。

get_url(request) 的一个常见用例是在项目中包含用于生成导航菜单的任何自定义模板标签中调用。在编写这样的自定义模板标签时,请确保它包括 takes_context=True 并使用 context.get(‘request’) 来安全地传递请求,或者如果上下文中不存在请求,则传递 None。

有关更多信息,请参阅 wagtail.models.Page.get_url()。

要检索完整的URL(包括协议和域),请使用 Page.get_full_url(request)。在可能的情况下,应包括可选的 request 参数,以启用每个请求的站点级URL信息的缓存。

有关更多信息,请参阅 wagtail.models.Page.get_full_url()。

模板渲染

每个页面模型都可以被分配一个 HTML 模板,当用户在站点前端浏览到页面时,该模板将被呈现。这是将 Wagtail 内容传递给最终用户的最简单和最常见的方式之一(但不是唯一的方式)。

为页面模型添加模板

Wagtail会根据应用标签和模型类名自动选择模板的名称。

格式: <app_label>/<model_name(蛇形命名)>.html例如,上述博客页面的模板将是: blog/blog_page.html

你只需在可以使用这个名称访问的位置创建一个模板。

模板上下文

Wagtail通过将页面变量绑定到正在渲染的页面实例来呈现模板。使用这个变量来访问页面的内容。例如,要获取当前页面的标题,请使用 {{ page.title }}。上下文处理器提供的所有变量也都可用。

自定义模板上下文

所有页面都有一个 get_context 方法,每当模板被渲染时都会调用该方法,并返回一个要绑定到模板中的变量字典。

要向模板上下文添加更多变量,您可以覆盖此方法:

class BlogIndexPage(Page):...def get_context(self, request, *args, **kwargs):context = super().get_context(request, *args, **kwargs)# Add extra variables and return the updated contextcontext['blog_entries'] = BlogPage.objects.child_of(self).live()return context

然后,这些变量可以在模板中使用:

{{ page.title }}{% for entry in blog_entries %}{{ entry.title }}
{% endfor %}

更改模板

将模板属性设置在类上,以使用不同的模板文件:

class BlogPage(Page):...template = 'other_template.html'

动态选择模板

可以通过在页面类上定义 get_template 方法,以在每个实例基础上动态更改模板。该方法在每次渲染页面时都会被调用:

class BlogPage(Page):...use_other_template = models.BooleanField()def get_template(self, request, *args, **kwargs):if self.use_other_template:return 'blog/other_blog_page.html'return 'blog/blog_page.html'

在这个例子中,拥有设置了 use_other_template 布尔字段的页面将使用 blog/other_blog_page.html 模板。所有其他页面将使用默认的 blog/blog_page.html 模板。

Ajax 模板

如果您想要向页面添加 AJAX 功能,例如在页面上直接更新而不是触发完整的页面重新加载的分页列表,您可以设置 ajax_template 属性来指定在通过 AJAX 调用请求页面时使用的替代模板(由 X-Requested-With: XMLHttpRequest HTTP 头指示):

class BlogPage(Page):...ajax_template = 'other_template_fragment.html'template = 'other_template.html'

对页面渲染的更多控制
所有页面类都有一个 serve() 方法,内部调用 get_context 和 get_template 方法,并呈现模板。这个方法类似于一个 Django 视图函数,接受一个 Django Request 对象,并返回一个 Django Response 对象。

这个方法也可以被覆盖,以完全控制页面的渲染。

例如,下面是使页面以其自身的 JSON 表示响应的一种方法:

from django.http import JsonResponseclass BlogPage(Page):...def serve(self, request):return JsonResponse({'title': self.title,'body': self.body,'date': self.date,# Resizes the image to 300px width and gets a URL to it'feed_image': self.feed_image.get_rendition('width-300').url,})

内联模型

Wagtail 允许在页面内嵌套其他模型。这对于创建重复字段,如相关链接或在轮播中显示的项目,非常有用。内联模型的内容也与页面的其余部分一起进行版本控制。

每个内联模型都需要以下内容:

必须继承自 wagtail.models.Orderable。
必须具有到父模型的 ParentalKey。

模型内联功能由 django-modelcluster 提供,ParentalKey 字段类型必须从该模块导入:

from modelcluster.fields import ParentalKey

ParentalKey 是 Django 的 ForeignKey 的子类,并接受相同的参数。

例如,以下内联模型可用于向 BlogPage 模型添加相关链接(名称、URL 对的列表):

from django.db import models
from modelcluster.fields import ParentalKey
from wagtail.models import Orderableclass BlogPageRelatedLink(Orderable):page = ParentalKey(BlogPage, on_delete=models.CASCADE, related_name='related_links')name = models.CharField(max_length=255)url = models.URLField()panels = [FieldPanel('name'),FieldPanel('url'),]

要将这个添加到管理员界面中,请使用 InlinePanel 编辑面板类:

content_panels = [...InlinePanel('related_links', label="Related links"),
]

第一个参数必须与 ParentalKey 的 related_name 属性的值匹配。有关 InlinePanel 接受的参数的简要描述,请参阅 InlinePanel。

在多个页面类型之间重用内联模型

在上面的例子中,相关链接被定义为 BlogPage 页面类型上的子对象。通常,相同类型的内联子对象将出现在多个页面类型上,在这些情况下,重复整个模型定义是不可取的。可以通过将共同的字段重构为抽象模型来避免这种情况:

from django.db import models
from modelcluster.fields import ParentalKey
from wagtail.models import Orderable# The abstract model for related links, complete with panels
class RelatedLink(models.Model):name = models.CharField(max_length=255)url = models.URLField()panels = [FieldPanel('name'),FieldPanel('url'),]class Meta:abstract = True# The real model which extends the abstract model with a ParentalKey relation back to the page model.
# This can be repeated for each page type where the relation is to be added
# (for example, NewsPageRelatedLink, PublicationPageRelatedLink and so on).
class BlogPageRelatedLink(Orderable,RelatedLink):page = ParentalKey(BlogPage, on_delete=models.CASCADE, related_name='related_links')

或者,如果 RelatedLink 将出现在您项目中定义的大量页面类型上,将一个单独的 RelatedLink 模型设置为指向基础的 wagtailcore.Page 模型可能更合适:

class RelatedLink(Orderable):page = ParentalKey("wagtailcore.Page", on_delete=models.CASCADE, related_name='related_links')name = models.CharField(max_length=255)url = models.URLField()panels = [FieldPanel('name'),FieldPanel('url'),]

然后,related_links 将作为跨所有页面类型的关联可用,尽管它仍然只能在包含了 InlinePanel 在其面板定义中的页面类型上进行编辑。对于其他页面类型,相关链接集将保持为空。

使用页面

Wagtail 使用 Django 的多表继承功能,允许在同一树中使用多个页面模型。

每个页面都被添加到 Wagtail 内置的 Page 模型和用户定义的模型(例如之前创建的 BlogPage 模型)。

页面可以以两种形式存在于 Python 代码中,即 Page 的实例或页面模型的实例。

在处理多个页面类型时,通常会使用 Wagtail 的 Page 模型的实例,这不会让你访问任何特定于其类型的字段。

# Get all pages in the database
>>> from wagtail.models import Page
>>> Page.objects.all()
[<Page: Homepage>, <Page: About us>, <Page: Blog>, <Page: A Blog post>, <Page: Another Blog post>]

在处理单个页面类型时,可以使用用户定义模型的实例。这样可以访问 Page 中的所有字段,以及该类型的任何用户定义字段。

# Get all blog entries in the database
>>> BlogPage.objects.all()
[<BlogPage: A Blog post>, <BlogPage: Another Blog post>]

可以使用 .specific 属性将 Page 对象转换为其更具体的用户定义等效项。这可能会导致额外的数据库查找。

>>> page = Page.objects.get(title="A Blog post")
>>> page
<Page: A Blog post># Note: the blog post is an instance of Page so we cannot access body, date or feed_image>>> page.specific
<BlogPage: A Blog post>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/612439.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hadoop之mapreduce参数大全-6

126.指定 Map 任务运行的节点标签表达式 mapreduce.map.node-label-expression 是 Hadoop MapReduce 框架中的一个配置属性&#xff0c;用于指定 Map 任务运行的节点标签表达式。节点标签是在 Hadoop 集群中为节点分配的用户定义的标签&#xff0c;可用于将 Map 任务限制在特定…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机图像转换由Mono10转换为Mono8(C++)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机图像转换由Mono10转换为Mono8&#xff08;C&#xff09; Baumer工业相机Baumer工业相机的Mono10转换为Mono8图的技术背景在NEOAPI SDK里实现相机图像由Mono10转换为Mono8格式 工业相机通过NEOAPI SDK实现相机图像转换的优…

Java入门高频考查基础知识1

Java语言是一种广泛应用于软件开发的高级编程语言&#xff0c;最初由Sun Microsystems于1995年发布。 以下是Java语言的一些特点和用途&#xff1a; 1. 跨平台性&#xff1a; Java是一种跨平台的编程语言&#xff0c;一次编写&#xff0c;到处运行&#xff08;Write Once, Run …

在ubuntu上检查内存使用情况的九种方法

在 Ubuntu 中&#xff0c;可以通过 GUI(图形用户界面)和命令行使用多种方法来监视系统的内存使用情况&#xff0c;监视 Ubuntu 服务器上的内存使用情况并不复杂&#xff1b;了解已使用和可用的内存量对于故障排除和优化服务器性能至关重要&#xff0c;因为内存对系统 I/O 速度至…

极狐 GitLab 冷知识:使用 Email 也可以创建 Issue?

前言 在使用 GitLab 时&#xff0c;创建 Issue 和 Merge Request 的方法&#xff0c;除了常规的使用 GitLab Web UI 进行操作和通过 API 调用操作&#xff0c;还有一些比较好玩的&#xff0c;比如使用 Email 来创建。 Incoming email 如果是 Self-Manager 的 GitLab 用户&am…

高精度彩色3D相机:开启崭新的彩色3D成像时代

3D成像的新时代 近年来&#xff0c;机器人技术的快速发展促使对3D相机技术的需求不断增加&#xff0c;原因在于&#xff0c;相机在提高机器人的性能和实现多种功能方面发挥了决定性作用。然而&#xff0c;其中许多应用所需的解决方案更复杂&#xff0c;仅提供环境的深度信息是…

分布式数据库原理及技术实验及个人思考

Hive的数据库及表的存储结构体系讨论&#xff1a; 1.显示hive所在数据库的位置 方法一&#xff1a;一次性临时存储 >hive set hive.cli.print.current.dbtrue 方法二&#xff1a;永久存储 在conf文件夹下修改hive-site.xml配置文件&#xff0c;添加 <property> …

mySQL⾥有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据

要确保Redis中只存储热点数据&#xff0c;你可以采取以下策略&#xff1a; 数据筛选: 在将数据插入MySQL之前&#xff0c;先通过某种算法或策略判断这条数据是否是热点数据。 可以基于数据的访问频率、时间戳或其他相关属性来决定是否将数据存储到Redis中。 LRU策略: 使用Re…

解决matplotlib中文乱码问题

一、修改配置文件&#xff0c;一劳永逸的方法 1. 首先&#xff0c;下载SimHei字体&#xff08;即SimHei.tff包&#xff09;下载地址&#xff1a;SimHei.ttf|字体下载 2. 下载好之后&#xff0c;找到matplotlib文件夹&#xff0c;如下图所示&#xff1a; 如果找不到matplotlib…

基于JavaWeb+BS架构+SpringBoot+Vue智能菜谱推荐系统的设计和实现

基于JavaWebBS架构SpringBootVue智能菜谱推荐系统的设计和实现 文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 文末获取源码 Lun文目录 目 录 目 录 III 第一章 概述 1 1.1 研究背景 1 1.2研究目的及意义 1 1.3…

Digital Audio (HDMI)未插入 用Hdmi连接电脑 显示高清数字音频未插入 win10电脑没声音,喇叭上一个叉❌

先说结论&#xff0c;出现这些问题的原因&#xff1a; 未插入音频设备或者硬件问题&#xff08;10%&#xff09;设置错误&#xff0c;未使用显示器音频 &#xff08;30%&#xff09;音频驱动不兼容或者没有驱动&#xff08;50%&#xff09;其他驱动有问题 &#xff08;10%&…

12. VTK上选取点(VTK7版本+VTK9版本)

这个专栏是用于记录我在学习VTK过程中的一些心得体会。参考的资料主要有以下三个&#xff1a; 1. 张晓东 罗火灵《VTK图形图像开发进阶》2. https://examples.vtk.org/site/3. 沈子恒 《VTK 三维数据渲染进阶》 遇到的一个大问题就是由于版本更新&#xff0c;这些资料中很多代…

“Tab“ 的新型可穿戴人工智能项链

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

少儿编程 2023年12月中国电子学会图形化编程等级考试Scratch编程三级真题解析(判断题)

2023年12月scratch编程等级考试三级真题 判断题 19、下列两段程序的运行效果相同 答案:对 考点分析:考查积木综合使用,重点考查循环积木的使用;左边属于有条件的循环,由变量的值控制,当变量值大于50时,循环停止,而变量始终为零,不满足条件,所以一直循环,和右边的…

DOM操作怎样添加、移除、移动、复制、创建和查找节点

DOM&#xff08;Document Object Model&#xff09;操作是JavaScript中用于操作HTML或XML文档的一种方式。下面是一些基本的DOM操作&#xff1a; 添加节点 使用appendChild()方法可以将一个节点添加到现有节点的子节点列表的末尾。 let newNode document.createElement(“p”…

Go语言的sync.Pool如何使用?使用场景具体有哪些?

sync.Pool 是 Go 标准库中提供的一个对象池&#xff08;Object Pool&#xff09;的实现。对象池是一种用于缓存和复用对象的机制&#xff0c;可以在一定程度上减轻内存分配的开销。sync.Pool 专门用于管理临时对象&#xff0c;适用于一些需要频繁创建和销毁的短暂对象&#xff…

Golang 泛型

前言 泛型是在Go 1.18版本中引入的&#xff0c;它允许编写可以在多种数据类型上工作的函数和数据类型。这样做可以增加代码的复用性并减少重复 使用 类型参数&#xff08;Type Parameters&#xff09;&#xff1a; 你可以在函数或类型定义上声明类型参数&#xff0c;使其具有…

白嫖aws创建Joplin server服务器

网上有很多的Joplin服务器的搭建教程&#xff0c;但是基本都是抄来抄去&#xff0c;对初学者实在是太不友好了。 话不多说&#xff0c;说干就干&#xff0c;自己从头找资料搭了一个&#xff0c;这可能是全网最好的Joplin服务器搭建教程了。 aws服务器 aws的服务器还是很香的&…

企业用WhatsApp营销的好处有哪些?

1.建立良好的客户关系 WhatsApp是全球用户喜爱的即时通信软件&#xff0c;使用WhatsApp与客户沟通&#xff0c;可拉进企业和客户双方的距离。使用WhatsApp会话和消息推送功能&#xff0c;企业和用户可实时开展消息对话&#xff0c;及时解决客户咨询与疑虑&#xff0c;构建便捷…

移动通信原理与关键技术学习之信道编解码(5)

先回顾调制的过程&#xff1a;调制就是对信号源的信息进行处理加到载波上&#xff0c;使其变为适合于信道传输的形式的过程&#xff0c;就是使载波随信号而改变的技术。 1.什么是IQ调制&#xff1f; 答&#xff1a;将数据分为两路&#xff0c;分别进行载波调制&#xff0c;两…