Django之 ArrayAgg与Admin技巧学习
Django Admin 技巧
有这样一个需求, Django 后台 admin 有一个 select 字段, 其备选项是某个系统路径下的文件名, 因此下拉列表的备选项是动态的.
而常规的 select 声明方式如下, 其备选项 choices 是静态的. 如果目标路径的文件发生变动, 必须重启 django 才能获得更新后的下拉列表.
name = models.CharField(max_length=64, choices = (('0','file1'),('0','file1')))
一个自然思路就是, 重载admin的 formfield_for_choice_field()
, 在函数内部调用下拉列表获取方法.
但问题是, 一旦选择的值不在上面声明的 choices
中, 表单验证就会失败.
正确的做法是取消 choices 约束, 将字段变成纯字符串型.
name = models.CharField(max_length=64)
这时候, admin 对name的 widget 会由 select 变为 input, 这不是我们想要的. 所以需要手动指定:
class RouteForm(forms.ModelForm): class Meta: widgets = { 'name': forms.Select(), } class RouteAdmin(TreeAdmin): form = RouteForm def formfield_for_dbfield(self, db_field, request, **kwargs): if db_field.name == 'name': choices = TextChoices( 'RouteName', get_files() ) kwargs['widget'].choices = choices.choices return super().formfield_for_dbfield(db_field, request, **kwargs)
这时候, 需要重载的函数就变为了 formfield_for_dbfield()
, 按照上述方式构造的admin,就能够实现业务需求.
Django 技巧之 ArrayAgg
PostgreSQL 提供了聚合类 ArrayAgg, 能够方便的完成列表的聚合.
Returns a list of values, including nulls, concatenated into an array, or default if there are no values.
例如
class Item(models.Model): name = models.CharField(max_length=20) class A(models.Model): name = models.CharField(max_length=20) items = models.ManyToManyField(to=Item)
打算将A模型序列化成以下形式
[ { "id": 1, "name": "名称1", "item_list": [ 410,415,416] }, { "id": 2, "name": "名称2", "item_list": [ 411,415,416] }, ]
也就是说, 将 ManyToManyField 这种外键直接序列化成列表形式. 这时候可以采用下述方式
A.objects.annotate( item_list=ArrayAgg('items',distinct=True)).values( 'id', 'name', 'item_list')
非常简洁优雅,且这是数据库底层支持的函数, 所有运行效率也非常高.
可以看出, Django项目采用 PostgreSQL 作为数据库还是非常有价值的.
以上就是Django之 ArrayAgg与Admin技巧学习的详细内容,更多关于Django技巧ArrayAgg Admin的资料请关注脚本之家其它相关文章!
相关文章
Python XlsxWriter模块Chart类用法实例分析
这篇文章主要介绍了Python XlsxWriter模块Chart类用法,结合实例形式分析了Python XlsxWriter模块Chart类功能、图表绘制常用方法及相关操作注意事项,需要的朋友可以参考下2019-03-03
最新评论