#django
#django
Вопрос:
Скажем, у меня есть следующая модель:
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())
Вышесказанное работает так:
- При создании миграций он не будет вызывать API для установки всех параметров в файле миграции
- Он управляется из серверной части, поэтому он работает со всеми формами модели, как в django admin.
- Администратор Django отображает метку вместо необработанного значения в отображении списка (
MachineChoices
для эффективности требуется реализованное кэширование)
Я не чувствую, что это элегантно, поскольку это связано с хакерством, чтобы обмануть django, особенно во время миграции.
Я знаю, что альтернативой является использование библиотек автозаполнения, но мне нужно настроить с помощью django forms.
Итак, есть ли лучшие способы сделать это?
Комментарии:
1. вы можете использовать
__init__
метод form для инициализации выбора.
Ответ №1:
Вместо этого вы можете установить choices
значение None
(или пустой список) AppConfig
.
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
Не забудьте включить свой AppConfig
in INSTALLED_APPS
.
mysite/settings.py:
INSTALLED_APPS = [
# ...
'myapp.apps.MyAppConfig',
]