Django动态获取mysql连接,django model中的choices 动态从数据库中获取

django model中的choices 动态从数据库中获取

例如

model中,有一个type字段

type = models.CharField(max_length=255, default='BOSS', verbose_name="配置类型",choices=(('boss','boss'),('bass','bass'),))

现在需要从数据库中动态指定该字段的choices,取值的方法为:

# 获取计划类型列表

def get_type_list():

return PlanType.objects.values_list("name", "name")

错误方法:

直接

type = models.CharField(max_length=255, default='BOSS', verbose_name="配置类型",choices=get_type_list())

弊端:

数据库中修改了以后,要重启django应用才能加载

解决方案:

重写model的构造方法,在构造方法中指定该字段的choices即可

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

super(PlanItemConfig, self).__init__(*args, **kwargs)

self._meta.get_field('type').choices = get_type_list()

问题:

调用self._meta毕竟是内部属性,不是太推荐使用

这种方法还有一个问题,定义字段的时候,方法中不能有filter,假如有filter,就会报

django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.

只能写成全部,可以在 __init__方法中,更新choices的时候,需要使用filter就用filter

我发现在数据库中修改了对应的值后,choises要刷新两次页面才能更新,具体原因未知

此方法还有一个致命的问题:

makemigrations的时候,会执行每个Model的init的方法,此处会执行数据库查询然后变更choices,最后体现在makemigrations生成的py文件中,在多人合作开发的项目中,会造成migrations有问题。

还有一种方法是self.fields['type'].choices更新choices字段。

不过这种方法也有问题,在列表中无效,必须进入编辑页面才能更新choices

可以定义一个ModelForm,在init方法中,更新

class ConfigForm(forms.ModelForm):

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

super(BillingFileMQConfigForm, self).__init__(*args, **kwargs)

# 每次刷新页面都要重新获取choices的值

self.fields['type'].choices = PlanType.objects.values_list("name", "name")

class Meta:

model = Config

fields = '__all__'

然后在ModelAdmin中,指定Form即可

form = ConfigForm

这两种方法各有优劣,方法一可以在admin的列表中展现choices的内容,使用隐藏字段,多人makegrations会有问题。

后来改用了方法二

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值