Динамическое создание вариантов в django
Я пытаюсь динамически заполнить выбор в форме django, выбор происходит из внешнего API. Моя модель на данный момент:
from django.db import models
class MyModel(models.Model):
choice_field = models.CharField(max_length=100, choices=())
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
api_url = 'http://api.com'
response = requests.get(api_url)
if response.status_code == 200:
data = response.json()
options = [(option['value'], option['label']) for option in data]
self._meta.get_field('choice_field').choices = options
однако, он не работает, может ли кто-нибудь помочь мне?
если вы можете использовать Django 5.0; из документации:
choices также может быть определен как вызываемый объект, который не ожидает никаких аргументов и возвращающий любой из форматов, описанных выше. Например:
def get_currencies(): return {i: i for i in settings.CURRENCIES} class Expense(models.Model): amount = models.DecimalField(max_digits=10, decimal_places=2) currency = models.CharField(max_length=3, choices=get_currencies)
Передача вызываемой переменной для
choices
может быть особенно удобной, когда, например. например, варианты:результат операций, связанных с вводом-выводом (которые потенциально могут быть кэширования), например запрос таблицы в той же или внешней базе данных, или доступ к выбору из статического файла. список, который в основном стабилен, но может меняться время от времени. стабилен, но может меняться время от времени или от проекта к проекту. Примеры из этой категории - использование сторонних приложений, предоставляющих известный перечень значений, таких как валюты, страны, языки, часовые пояса и т. д.
так что в основном вы будете делать следующее:
def get_choices:
api_url = 'http://api.com'
response = requests.get(api_url)
if response.status_code == 200:
data = response.json()
return [(option['value'], option['label']) for option in data]
else:
pass #error handling here
#---------------------------------
from django.db import models
class MyModel(models.Model):
choice_field = models.CharField(max_length=100, choices=get_choices)
Также обратите внимание на следующее из документации:
Обратите внимание, что выбор может быть любым объектом последовательности - не обязательно списком или кортеж. Это позволяет создавать варианты динамически. Но если вы обнаружите, что что вам нужно динамически изменять
choices
, то, вероятно, лучше использовать использовать соответствующую таблицу базы данных сForeignKey
.choices
предназначен для статических данных, которые меняются нечасто, если вообще меняются.