我有一个多租户应用程序,其中每个“租户”(公司模型对象)都有多个客户端。每个租户可以设置其应用所需的必填字段。
class Client(models.Model):
"""
Client information
"""
company = models.ForeignKey(Company, blank=True, null=True, default=1, on_delete=models.SET_NULL)
name = models.CharField(max_length=150, blank=True)
email = models.EmailField(max_length=255, unique=True)
phone_number = models.CharField(max_length=50, blank=True, null=True)
class RequiredClientFields(models.Model):
"""
Let each business decide how to enforce the data filling requirements for its staff/clients.
0 - dont even show it
1 - show it, but dont require (default)
2 - require field for either staff or client
3 - require for clients when self-filling their form, but not the staff members
"""
company = models.ForeignKey(Company, db_index=True, on_delete=models.CASCADE)
field_name = models.CharField(max_length=50)
status = models.PositiveSmallIntegerField(choices=FIELD_STATUS_CHOICES, default=1)
因此,在创建要在模板上使用的django表单时,根据公司的政策,显示(验证)每个字段的最佳方法是什么?
感谢
类似这样的方法可能会起作用。
声明一个ModelForm并用删除字段或更改其__init__()
状态的逻辑覆盖required
:
class ClientForm(forms.ModelForm):
class Meta:
model = Client
fields = '__all__'
def __init__(self, company, user, *args, **kwargs):
super(ClientForm, self).__init__(*args, **kwargs)
# For each RequiredClientFields instance,
# get the matching form field and make changes
for rule in RequiredClientFields.objects.filter(company=company):
# get the form field
field = self.fields.get(rule.field_name, None)
if field:
if rule.status == 0:
# remove field from form
self.fields.pop(rule.field_name)
elif rule.status == 2:
# require field
field.required = True
elif rule.status == 3 and not user.is_staff:
# require for clients when self-filling their form,
# but not the staff members
field.required = True
然后在您的视图中创建ModelForm的实例,为公司和用户传递参数。
company = Company.objects.get(pk=1)
client_form = ClientForm(company=company, user=request.user)
请注意,以这种方式控制表单字段时可能存在安全隐患。看看Django ModelForm文档中的relevant section。