我试图一起使用autocomplete_light和django-dynamic-formset:两者都是单独工作但我不能让它们一起工作......让我们从代码开始......
models.py:
class Tmp_User(models.Model):
userName = models.CharField(max_length=200, blank=True, null=True,)
firstName = models.CharField(max_length=200, blank=True, null=True,)
lastName = models.CharField(max_length=200, blank=True, null=True,)
...
class Project(models.Model):
title = models.CharField()
...
class Segment_in_Project(models.Model):
name = models.CharField()
the_project = models.ForeignKey('Project')
translator = models.ForeignKey('Tmp_User')
...
forms.py
autocomplete_light.autodiscover()
class AddProjectForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(AddProjectForm, self).__init__(*args, **kwargs)
class Meta:
model = Project
fields = '__all__'
class AddSegmentForm(autocomplete_light.ModelForm):
def __init__(self, *args, **kwargs):
super(AddSegmentForm, self).__init__(*args, **kwargs)
class Meta:
model = Segment_in_Project
autocomplete_exclude = ['the_project']
fields = '__all__'
SegmentFormSet = formset_factory(AddSegmentForm)
autocomplete_light_registry.py
autocomplete_light.register(Tmp_User,
search_fields=['^firstName', 'lastName'])
和views.py
class ProjectCreateView(CreateView):
model = Project
template_name = 'home/formset-table.html'
form_class = AddProjectForm
success_url = '/admin'
def get(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
formset = SegmentFormSet()
return self.render_to_response(
self.get_context_data(
form_Project=form,
formset_Segment=formset))
def post(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
formset = SegmentFormSet(self.request.POST)
if (form.is_valid() and formset.is_valid()):
return self.form_valid(form, formset)
else:
return self.form_invalid(form, formset)
def form_valid(self, form, formset):
self.object = form.save()
self.object.save()
formset.instance = self.object
formset.save()
return super(ProjectCreateView, self).form_valid(form)
def form_invalid(self, form, formset):
return self.render_to_response(
self.get_context_data(
form_Project=form, formset_Segment=formset))
问题是formset实例不是"绑定"到项目模型并且验证失败:错误告诉the_project
未定义...我尝试先保存表单,获取新保存项目的ID并将其与请求一起传递给formset .POST,当我提出形式集...但它没有工作......
另一方面,使用inlineformset_factory(Project,Segment_in_Project)
代替formset_factory
会破坏autocomplete_light功能...(我不知道如何将autocomplete_light.ModelForm
用于Segment_in_Project formset)
关于如何做的任何想法或建议?感谢
答案 0 :(得分:0)
行。经过大量尝试后,我找到了解决方案。从某种意义上讲,它不是完美的,它可以满足我的需求,但我仍然感觉应该有更好的东西......
无论如何,我所做的就是完全破解post函数:我首先保存ProjectModel,然后我获取已保存项目的id,然后我读取了formset POST信息(它没有关于ID的任何信息)刚刚创建的项目),获取我需要的信息并使用正确的项目ID构建一个新的formset然后我保存它。代码如下:
def post(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
form.instance.created_by = self.request.user
formset = SegmentFormSet(self.request.POST)
if form.is_valid():
self.object = form.save()
newdata = {}
for idx, form in enumerate(formset):
for field in form.fields:
print idx, field, form[field].value()
if field == 'the_project':
tmp_field = u"form-%s-the_project"%(idx)
newdata[tmp_field] = self.object.id
elif field == 'id':
pass
else:
tmp_field = u"form-%s-%s"%(idx,field)
newdata[tmp_field] = form[field].value()
newdata[u"form-MAX_NUM_FORMS"] = u"1000"
newdata[u"form-MIN_NUM_FORMS"] = u"0"
newdata[u"form-INITIAL_FORMS"] = u"0"
newdata[u"form-TOTAL_FORMS"] = len(formset)
newdata[u"title"] = self.object.title
new_formset = SegmentFormSet(newdata)
if new_formset.is_valid():
return self.form_valid(form, new_formset)
else:
return self.form_invalid(form, new_formset)
如您所见,newdata DICT正是我所需要的(包括项目ID),用于正确保存SegmentFormSet。
如果有人有更好的解决方案......请告诉我