热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

各种动态Django表单集引发missing_management_form错误

当我动态构建多个表单集时,我无法验证Django表单集在这种情况下,一个客户可

当我动态构建多个表单集时,我无法验证Django表单集
在这种情况下,一个客户可以是各种品牌和联系人。

models.py

class Client(ChangesMixin,models.Model):
name = models.CharField(verbose_name="Nombre",max_length=100,unique=True)
code = models.PositiveIntegerField(verbose_name="Código",blank=True)
class Meta:
verbose_name = "Cliente"
verbose_name_plural = "Clientes"
class Brand(ChangesMixin,models.Model):
name = models.CharField(verbose_name="Marca",blank=True,null=True)
client = models.ForeignKey('Client',verbose_name="Cliente",related_name='brand_client',on_delete=models.DO_NOTHING)
class Meta:
verbose_name = "Marca"
verbose_name_plural = "Marcas"
class Contact(ChangesMixin,models.Model):
name = models.CharField(verbose_name="Contacto",null=True)
client = models.ForeignKey('Client',related_name='contact_client',on_delete=models.DO_NOTHING)
class Meta:
verbose_name = "Contacto"
verbose_name_plural = "Contactos"

我有两种方法可以动态创建表单和表单集

forms.py

def get_custom_formset(entry_model=None,entry_fields=None,action=None):
formset = None
if action == 'create':
extra = 1
else:
extra = 0
formset = modelformset_factory(
model = entry_model,extra = extra,form = get_custom_form(entry_model,entry_fields,action)
return formset
def get_custom_form(entry_model=None,action=None):
class _CustomForm(forms.ModelForm):
class Meta:
model = entry_model
fields = [field.name for field in entry_fields]
def __init__(self,*args,**kwargs):
"""
"""
super(_CustomForm,self).__init__(*args,**kwargs)
instance = getattr(self,'instance',None)
if instance and instance.pk:
for field in entry_fields:
if action == 'detail':
self.fields[field.name].widget.attrs['readonly'] = True
return _CustomForm

我有一个带有get和post方法的创建类视图,取决于传递的模型。
我得到模型字段来构建表单,如果字段是外键,我将使用这些具体模型来构建表单集。

views.py

class CustomCreateView(LoginRequiredMixin,View,PermissionRequiredMixin):
model = None
template = 'create.html'
def get(self,request,**kwargs):
template_form = str(self.model._meta.verbose_name).lower() + "_form.html"
model_fields = self.model._meta.get_fields()
form = None
formset = None
formsets = {}
for main_field in model_fields:
main_field_name = main_field.__class__.__name__
if main_field_name == 'ManyToOneRel':
model_names = str(main_field.name).split("_")
submodel = apps.get_model('app',model_names[0])
submodel_fields = submodel._meta.get_fields()
formset = app_forms.get_custom_formset(submodel,submodel_fields,'create')
queryset = submodel.objects.none()
UPDATED with SOLUTION
formset = formset(queryset=queryset,prefix=submodel.__name__.lower())
formsets[submodel._meta.verbose_name.lower()] = formset
elif main_field_name == 'ManyToManyField':
print("NOT PROVIDED YET")
form = app_forms.get_custom_form(self.model,model_fields,'create')
form = form(prefix=self.model.__name__.lower())
return render(request,self.template,{
'form': form,'formsets': formsets,'template_form': template_form,})
def post(self,**kwargs):
template_form = str(self.model._meta.verbose_name).lower() + "_form.html"
model_fields = self.model._meta.get_fields()
for main_field in model_fields:
main_field_name = main_field.__class__.__name__
if main_field_name == 'ManyToOneRel':
model_names = str(main_field.name).split("_")
submodel = apps.get_model('app','create')
queryset = submodel.objects.none()
formset = formset(queryset=queryset,prefix=submodel.__name__.lower())
formsets[submodel.__name__.lower()] = formset
elif main_field_name == 'ManyToManyField':
print("NOT PROVIDED YET")
form = app_forms.get_custom_form(self.model,'create')
form = form(request.POST,prefix=self.model.__name__.lower())
for prefix,formset in formsets.items():
formset = formset.__class__(request_post,prefix=prefix)
if formset.is_valid() and form.is_valid(): HERE THROWS THE ERROR

对于模板,我有3个级别来动态构建表单和表单集

create.html

{% get_url urls 'create' as element_create %}

{% csrf_token %}
{% include template_form %}
{% if formsets|length > 0 %}
{% for subtemplateformname,formset in formsets.items %}
{% include 'formset.html' %}
{% endfor %}
{% endif %}

formset.html

{{ formset.management_form }}
{% for form in formset %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% include 'form.html' %}
{% endfor %}

form.html

{% load widget_tweaks %}
{% for field in form %}



{{ field|add_class:"form-control" }}
{% for error in field.errors %}

{{ error }}


{% endfor %}

{% endfor %}

首先,当您获得相关模型的表单集时,您会通过sub_fields,但我不知道这是哪里来的?

formset = app_forms.get_custom_formset(submodel,sub_fields,'create')

错误与您定义表单集前缀的方式有关。在GET中,您传递model_names[0],对于正常的关系,模型名称将是小写字母,没有任何空格。例如,让我们使用名为MyModel的模型

main_field.name # 'mymodel_set'
model_names = str(main_field.name).split("_") # ['mymodel','set']
model_names[0] # 'mymodel'
formset = formset(queryset=queryset,prefix=model_names[0])

当您将表单集分配给formsets字典时,即使您使用相同的格式,也会使用不同的内容

formsets[submodel._meta.verbose_name.lower()] = formset
...
for prefix,formset in formsets.items():
formset = formset.__class__(request_post,prefix=prefix)

submodel._meta.verbose_name将返回带有空格的模型名称。因此,任何名称中带有2个“单词”的模型都不会设置正确的前缀(例如MyModel._meta.verbose_name.lower() == 'my model'却是model_names[0] == 'mymodel'


推荐阅读
author-avatar
Three-Kobe
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有