python - 基于 CharField 选择动态生成 Django 表单
问题描述
我有一个用户配置文件模型,它存储了许多第三方 API 密钥的配置,我试图确定如何最好地根据用户所做的选择动态生成表单。该应用程序仅支持一部分服务,因此我使用CharField
(+ CHOICES
) 来缩小用户尝试提交配置的范围。用户可以提交任意数量的副本(Cloud Service 1
例如 3 组密钥)
我有这个模型:
class ServiceIntegration(models.Model):
profile = models.ForeignKey(
Profile,
on_delete=models.CASCADE
)
CS1 = 'CS1'
CS2 = 'CS2'
SERVICE_CHOICES = (
(CS1, 'Cloud Service 1'),
(CS2, 'Cloud Service 2'),
)
alias = models.CharField(max_length=255)
service = models.CharField(
max_length=255,
choices=SERVICE_CHOICES,
default=CS1
)
config = JSONField()
在表单中,用户有一个下拉列表,其 QuerySet 设置为此模型的对象。当用户进行选择时,我想联系一个端点并将一些表单 HTML 转储到预定位置。据推测,我可以为每个集成设置一个表单,并简单地拥有一个接受选择、查找表单并将其呈现出来的视图(将数据发布到该端点也是如此)。
根据用户的选择动态呈现表单(并接受数据)的最佳选择是什么?
解决方案
我最终编写了每个集成实现都继承自的 BaseService 类,以及每个实现返回的表单,例如:
from service_integrations.forms import CloudServiceOneForm
class BaseService(ABC):
def __init__(self, configuration):
self.configuration = configuration
super().__init__()
@abstractmethod
def get_form(self):
pass
@abstractmethod
def get_service_name(self):
pass
@abstractmethod
def check(self):
pass
@abstractmethod
def run(self):
pass
class CloudServiceOne(BaseService):
def get_service_name(self):
return 'Cloud Service One' # This should match the CharField Choice
def get_form(self):
return CloudServiceOneForm()
def check(self):
# Requirements for config go here
if self.configuration.get('secret_key') and self.configuration.get('access_key'):
return True
else:
return False
def run(self):
pass
以及可以从视图调用以将相关表单传递到上下文的实用程序:
from service_integrations.classes import BaseService
def get_service(service):
# Passes empty configurations to each subclass of BaseService and returns the handler based on the name.
for cls in BaseService.__subclasses__():
if cls({}).get_service_name() == service:
return cls
return None
然后您可以将表单传递到上下文中,例如:
service = get_service('Cloud Service One')
context = {
'form': service.get_form()
}
return render(request, 'some_template.html', context)
推荐阅读
- asp.net - 使用代码优先的方法,我没有 edmx 文件。有什么选择?
- operating-system - CPU调度中的到达时间是否可能相同?
- javascript - 运行节点 server.js 和重新播种 db 时,表会被删除。续集
- javascript - 如何在codeigniter和edit中使用获取某个用户的数据不起作用
- angular - Angular 6 视图未更新,即使使用 ChangeDetectorRef、ngZone 和 requestAnimationFrame
- variables - Lua:检查局部或全局变量
- runtime-error - 无法获取管理权限。运行时错误:无法执行命令 chcp
- ruby-on-rails - 下划线在 ruby on rails 中的 axlsx 中不起作用
- python - 如何将 MultiIndex 数据框列与简单数据框匹配并相乘?
- javascript - NodeJS res.on() 没有被触发。res.on() 不是函数