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_

  • Herald Yu
    Herald Yu
1 min read
Wagtail

Django/Wagtail debug=False 出现 500 错误

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

  • Herald Yu
    Herald Yu
1 min read
Wagtail

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

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

  • Herald Yu
    Herald Yu
2 min read
Django

Django for 循环计数

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

  • Herald Yu
    Herald Yu
1 min read
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.

  • Herald Yu
    Herald Yu
1 min read
Django

Django template 标签和过滤器

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

  • Herald Yu
    Herald Yu
1 min read
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=

  • Herald Yu
    Herald Yu
2 min read
Wagtail

Wagtail 子页面排序

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

  • Herald Yu
    Herald Yu
2 min read
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/

  • Herald Yu
    Herald Yu
1 min read
Wagtail

Wagtail Snippets 代码片段

Snippets 是一段不必成为一个完整网页的内容片段。它可以被用于制作二级内容,例如页头、页脚和边栏,这些内容可以在 Wagtail admin 中编辑。虽然 Snippets 也是 Django 模型,但却不继承自 Page 类,也不属于 Wagtail tree 结构中。然而,它们仍旧可以通过 register_snippet 类修饰器将模型关联到管理面板并作为一个代码片段被编辑。 相比 Pages,Snippets 缺少许多功能,例如在 Wagtail admin

  • Herald Yu
    Herald Yu
1 min read
Wagtail

Wagtail 使用 s3 存储不显示 icon

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

  • Herald Yu
    Herald Yu
1 min read

Subscribe to Herald's Tech Notes