Динамическое создание вариантов в 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 предназначен для статических данных, которые меняются нечасто, если вообще меняются.

Вернуться на верх