Wagtail

A collection of 23 posts

Wagtail

Wagtail - How to using Documents

Watail 预置功能除了非常方便好用的 Images 以外,还有 Documnets,用法与 images 类似。 由于 images 模块仅支持上传 jpg、gif、png 这三种常见格式的图片,而现在网站 logo 通常会采用矢量的 svg 格式,因此我考虑改用 documents 来处理其他格式图片的上传。 from wagtail.documents.edit_handlers import DocumentChooserPanel class HomePage(Page): book = models.ForeignKey( 'wagtaildocs.Document', null=True, blank=True, on_

Django

Django 项目开始前先自定义 User Model

Django 官方文档的自定义身份认证部分有这样一句话: If you’re starting a new project, it’s highly recommended to set up a custom user model, even if the default User model is sufficient for you. 如果您正在启动一个新项目,强烈建议设置一个自定义用户模型,即使默认的用户模型对您来说已经足够了。 如果是边开发边看文档,等读到这部分时,黄瓜菜都凉了。 项目文档编写自然有它的逻辑,不在文档最开始的时候提出这个建议也是为了不给新手造成困扰。换位思考,如果自己是初学者,连项目和应用的区别还没弄明白,文档入门一上来就告诉你先创建个自定义的用户应用,然后在模型里面继承某个抽象类定义个自定义用户模型,我一定马上把网页关掉。

Django

Django 模型使用 Wagtail Image

Wagtail 封装了理想的图片管理模块,大大减少了网站开发的工作量,在继续编写笔记之前,必须向 Wagtail 的开发者致敬! 绝大多数时候,网站项目都会超越 CMS 的范畴,如果能在普通的 DJango APP 上使用 Wagtial 的图片管理类,那一定是很感人的。 模型 在 Django 模型中,以外键的形式调用 wagtail Image 类。 from django import forms from django.db import models from wagtail.images.models import Image class Product(models.

Django

Django "Cannot drop column 'page_ptr_id': needed in a foreign key

Wagtail 提供的很多功能需要通过外键实现,应用创建的多了类写的多了就免不了将某个模型中的类和其外键类一并删除或改换其他地方。如果使用 sqlite 数据库,执行迁移并没有问题。但生产环境使用 mysql/mariadb 时就会出现标题所示的错误。 django.db.utils.OperationalError: (1829, "Cannot drop column 'page_ptr_id': needed in a foreign key constraint 'home_formfield_page_id_11ee50f3_fk_home_formpage_page_ptr_id' of table `myproject`.`home_

Wagtail

Django/Wagtail debug=False 出现 500 错误

生产环境肯定是要关闭 debug 的,开发环境运行的好好的,可是部署到生产环就给报一个 Error 500 内部服务器错误,debug=True 马上就能正常访问。这个问题有两个原因: 原因一 未配置允许的主机 生产环境配置文件 production.py 中有一行: ALLOWED_HOSTS = ['it.ismy.fun', '.ismy.fun'] 把站点使用的域名填进去。配置以后还是 500错误? 原因二 静态文件问题 生产环境中,Django 是不管静态文件的,所以我们要配置一个静态文件的存储后端。配置好后端,用 ./manage.py collectstatic 将程序中所有静态文件分发到存储后端,这样就一定能访问了。 解决方法:Wagtail/

Wagtail

Wagtail/Django 使用 S3-like 对象存储

本地开发使用 django 自带的服务器,静态文件直接在项目目录中托管。一旦要往生产环境部署时,就会发现必须为前端静态文件和其他媒体文件配置一个单独的存储后端,Django 说它不管这事儿。 存储后端可以直接在服务器上配置一个静态服务器,也可以直接使用 AWS S3 之类的对象存储,这里主要记录对象存储后端的配置方法。 对于 wagtail 来说,使用对象存储并不能让网站程序完全减负,很多对图片和文档的操作需要先将文件从对象存储取回到服务器的内存中,处理好以后再返回给访问者。Anyway,对象存储可以分担带宽,总之利大于弊。 第一步 安装存储管理相关的包 使用 django-storages 管理存储后端,使用 boto3 实现 s3-like 对象存储的管理。 $ pipenv install django-storages boto3 将包信息写入 requirements.txt 文件: $ pip freeze >

Django

Django 实现简单的文件上传

前端通过 Dropzone 组件上传文件到后端,因此需要准备一个简易的后端来处理上传请求。 这里创建了一个名为 topic 的 app,在应用目录下创建 urls.py 文件: from django.urls import path from . import views urlpatterns = [ path('upload/', views.image_upload, name='jdd_upload'), ] 在项目 urls.py 中引用: from django.conf.urls import include, url urlpatterns = [ url(r'^

Django

Django for 循环计数

碰到一个奇葩的前端设计,下拉列表切换不同的面板,用不同的面板来对同一个单选字段下的项进行分类。比如前3项在第一个 panel,随后的2项在第二个 panel,最后3项在第三个 panel。 这样一来就需要用 for 循环对这个项进行迭代,Django 手册有介绍 {{ forloop.counter }},把它扔进 for 循环里,会帮助计数,从 1 开始,如果想从 0 开始,可以使用 {{ forloop.counter0 }}。 如下,从第8项开始渲染: {% for i in form.topic %} {% if forloop.counter > 7 %} <p>

Wagtail

Wagtail 搜索字段为外键时的处理

Wagtail 封装了便利的字段搜索能力,在不做任何设置的情况下,它会默认搜索页面标题,任何需要被搜索的字段都可以直接在模型中进行定义,比如需要额外搜索品牌名称字段: from django.db import models from wagtail.core.models import Page from wagtail.search import index class CompanyPage(Page): brand = models.CharField( '品牌名', blank=False, null=False, max_length=250) search_fields = Page.search_fields + [、 index.SearchField('brand')

Wagtail

Wagtail snippets attached InlinePanel making sub-categories

眼前有个二级产品分类的需求,分类数据同时要给企业详情和其他一些在线表单调用,感觉用 wagtail 的 snippets 实现比较合适。 但我发现 wagtail 手册中 snippets 部分并没有提及附加子数据的内容。我模仿 Page 模型页面附加图集的方式,初步实现了这个需求。 from django.db import models from modelcluster.fields import ParentalKey from modelcluster.models import ClusterableModel from wagtail.core.models import Orderable from wagtail.admin.edit_handlers import FieldPanel,

Django

Django template 标签和过滤器

实现加法运算 想直接在模板中做形如 {% with number = 1 + 2 %} 的变量计算是不可能的,想让变量实现简单的相加可以通过 add 过滤器实现。 比如:我要构建一个字符串,page.year 变量会打印一个四位数的年份,如果想把它组成 2019-review 这样的字符串,可以这样写: {% slugurl page.year|add:'-review' %} slugurl 是 wagtail 中的一个根据 slug 生成 url 的标签。它与本例要记录的内容无关。 将 int 转换为 string 将数字 5 转换为字符串: {{ 5|stringformat:'i' }}

Wagtail

Wagtail custom default slug 自定义超链接默认值

默认情况下 Wagtail 的 slug(超链接缩略名)会沿用标题,对于中文频道就比较麻烦,因为超链接中有一段中文,从视觉效果和链接长度上来讲都不大科学。 可以通过重写 clean() 方法实现在保存页面之前,覆盖默认的 slug 等项的值: import time from django.utils.text import slugify class NewsPage(Page): title_pic = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+

Wagtail

Wagtail 子页面排序

与 Wordpress 对 post 和 page 做区分不同,wagtail 视一切为页面。比如一个新闻频道,所有的新闻都是索引页的子页面,它们与关于我们类似的单页面性质完全相同,可能最大的区别就是它们属于不同的父页面。 例如有这样一个索引模型: class NewsIndexPage(Page): # 允许创建子页面类型 subpage_types = ['news.NewsPage'] banner = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+', ) content_panels = Page.content_

Django

Django Template 日期格式化

{{ post.first_published_at | date:"Y-m-d" }} 打印当前时间 一般在页脚版权位会写上当前的年份,如果能自动显示当前年份就省去了每年手动更新的麻烦。特别是忘记更新的时候,那种网站无人维护的既视感对访客影响很大。通过 Django now filter 直接打印当前时间: {% now "Y" %} 格式化参数根据需要设置即可 Reference https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#now How to display the current year in a Django

Wagtail

Wagtail Snippets 代码片段

Snippets 是一段不必成为一个完整网页的内容片段。它可以被用于制作二级内容,例如页头、页脚和边栏,这些内容可以在 Wagtail admin 中编辑。虽然 Snippets 也是 Django 模型,但却不继承自 Page 类,也不属于 Wagtail tree 结构中。然而,它们仍旧可以通过 register_snippet 类修饰器将模型关联到管理面板并作为一个代码片段被编辑。 相比 Pages,Snippets 缺少许多功能,例如在 Wagtail admin 中排序或定义 URL。因此,应根据内容类型的需要谨慎决定是否使用。 在模版中使用 自定义标签 在应用目录中创建 templatetags 目录及 templatetags/my_

Django

Django migrate rollback 迁移回滚

Django 1.8+ 的版本可以通过以下命令实现回滚到上一个迁移(rollback to previous migrate)。 比如这里要操作的 app 是 news。 查看一个 app 的迁移列表 $ ./manage.py showmigrations news news [X] 0001_initial [X] 0002_auto_20190718_1016 [X] 0003_newsindexpage_banner 撤销最近一次的 migrate 重新执行其前一次提交,即可撤销最新的一个提交: $ ./manage.py migrate news 0002 撤销某个 app 的全部

Wagtail

Wagtail 使用 s3 存储不显示 icon

Wagtail 使用 S3 作为存储后端时,管理界面的 icon 图标不能正常显示。 这是因为 wagtail 使用了网络图标字体,而对象存储不允许从远端读取字体导致的。 解决方法一 在项目配置文件中找到 S3 存储的配置信息,添加以下配置后再重新执行 ./manage.py collectstatic。 AWS_HEADERS = { 'Access-Control-Allow-Origin': '*' } 这个方法是为每个上传到 S3 的对象设置一个专门的头记录,允许这个文件实现跨域访问。 解决方法二 这种方法是在平台上直接设置 CORS,不需要重新上传文件,立即生效,推荐。 对应的纯文本配置: <CORSConfiguration> <CORSRule> <AllowedOrigin>