在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
不过,这个方法没有成功,有人能帮我吗?
1 个回答
0
如果你能使用Django 5.0,可以参考文档中的内容:
你可以把选择项定义为一个不需要参数的可调用对象(也就是一个函数),这个函数会返回上面提到的任何格式。比如:
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
是用来存放那些不怎么变化的静态数据的。