我有一个用户配置文件模型,该模型存储了许多第三方API密钥的配置,我正在尝试确定如何最好地根据用户做出的选择动态生成表单。该应用程序仅支持一部分服务,因此我正在使用CharField
(+ CHOICES
)来缩小用户试图提交配置的范围。用户可以根据需要提交任意数量的重复项(例如3套Cloud Service 1
键)
我有这个模型:
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。大概,我可以为每个集成设置一个表单,只需有一个视图即可接受选择,查找表单,然后将其渲染回去(与将数据发布到该端点相同)。
根据用户的选择动态呈现表单(并接受数据)的最佳选择是什么?
答案 0 :(得分:0)
我最终编写了每个集成实现都继承自的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)