Django模型字段动态选择调用API



假设我有以下模型:

class DenyList(models.Model):
vm_id = models.CharField(max_length=25)

我想将选项添加到vm_id字段,但是这些选项是通过外部虚拟机注册表系统的API动态的。

所以我以以下方式完成:

class MachineChoices(object):
def get_vms(self):
if 'makemigrations' in sys.argv or 'migrate' in sys.argv:
return []
# calls api, optionally cache, return the vms
def __iter__(self):
yield from self.get_vms()

class DenyList(models.Model):
vm_id = models.CharField(max_length=25, choices=MachineChoices())

上面的工作原理是:

  1. 创建迁移时,它不会调用API来设置迁移文件中的所有选项
  2. 它是从后端驱动的,所以它可以在所有模型表单上工作,就像在django-admin中一样
  3. Django admin在列表显示中显示标签而不是原始值(为了提高效率,需要在MachineChoices中实现缓存(

我觉得这并不优雅,因为它涉及欺骗django的技巧,尤其是在迁移期间。

我知道另一种选择是使用自动完成库,但我需要使用django表单进行自定义。

那么,有什么更好的方法可以做到这一点吗?

您可以在AppConfig中将choices设置为None(或空列表(。

myapp/apps.py:

import sys
from django.apps import AppConfig

class MyAppConfig(AppConfig):
name = 'myapp'
def ready(self):
if 'makemigrations' in sys.argv or 'migrate' in sys.argv:
from . import models
models.Company.street_num.field.choices = None

如果您不想具体配置每个模型字段:

if 'makemigrations' in sys.argv or 'migrate' in sys.argv:
for model in self.models.values():
for field in model._meta.fields:
field.choices = None

请记住在INSTALLED_APPS中包含您的AppConfig

mysite/settings.py:

INSTALLED_APPS = [
# ...
'myapp.apps.MyAppConfig',
]

相关内容

  • 没有找到相关文章

最新更新