Python 在CreateView中将inlineformset_工厂与不同的查询集一起使用
我试图使用inlineformset_工厂创建同一模型的实例 型号.pyPython 在CreateView中将inlineformset_工厂与不同的查询集一起使用,python,django,Python,Django,我试图使用inlineformset_工厂创建同一模型的实例 型号.py class Skill(models.Model): employee = models.ForeignKey( Employee, on_delete=models.CASCADE, related_name="employee_skills") technology = models.ForeignKey(Technology, on_delete=models.CASCADE)
class Skill(models.Model):
employee = models.ForeignKey(
Employee, on_delete=models.CASCADE, related_name="employee_skills")
technology = models.ForeignKey(Technology, on_delete=models.CASCADE)
year = models.CharField('common year using amount ', max_length=4)
last_year = models.CharField('Last year of technology using ', max_length=4)
level = models.CharField("experience level", max_length=64, choices=LEVELS)
class Techgroup(models.Model):
""" Group of technology """
name = models.CharField('group_name', max_length=32, unique=True)
class Technology(models.Model):
"""Technologies."""
name = models.CharField('technology name', max_length=32, unique=True)
group = models.ForeignKey(Techgroup, on_delete=models.CASCADE, related_name="group")
class SkillBaseCreateForm(forms.ModelForm):
YEAR_CHOICES = [(r, r) for r in range(1, 11)]
LAST_YEAR_CHOICES = [(r, r) for r in range(2015, datetime.datetime.now().year + 1)]
year = forms.CharField(
widget=forms.Select(choices=YEAR_CHOICES),
)
last_year = forms.CharField(widget=forms.Select(choices=LAST_YEAR_CHOICES))
class Meta:
model = Skill
fields = ['technology', 'level', 'last_year', 'year']
class SkillCreatePLanguageForm(SkillBaseCreateForm):
def __init__(self, *args, **kwargs):
super(SkillCreatePLanguageForm, self).__init__(*args, **kwargs)
self.fields['technology'].queryset = Technology.objects.filter(group__name="Programming language")
class SkillCreateFrameworkForm(SkillBaseCreateForm):
def __init__(self, *args, **kwargs):
super(SkillCreateFrameworkForm, self).__init__(*args, **kwargs)
self.fields['technology'].queryset = Technology.objects.filter(group__name="Framework")
SkillFrameworkFormSet = inlineformset_factory(Employee, Skill, form=SkillCreateFrameworkForm, extra=1, can_delete=False)
SkillPLanguageFormSet = inlineformset_factory(Employee, Skill, form=SkillCreatePLanguageForm, extra=1, can_delete=False)
class SkillTestCreateView(AuthorizedMixin, CreateView):
"""
Create new skill instances
"""
template_name = 'edit.html'
model = Employee
form_class = EmployeeEditForm
def get(self, *args, **kwargs):
"""
Handles GET requests and instantiates blank versions of the form
and its inline formsets.
"""
self.object = Employee.objects.get(pk=self.kwargs['pk'])
form_class = self.get_form_class()
form = self.get_form(form_class)
form_framework = SkillFrameworkFormSet()
form_language = SkillPLanguageFormSet()
return self.render_to_response(
self.get_context_data(form=form,
form_framework=form_framework,
form_language=form_language))
def post(self, request, *args, **kwargs):
"""
Handles POST requests, instantiating a form instance and its inline
formsets with the passed POST variables and then checking them for
validity.
"""
self.object = Employee.objects.get(pk=self.kwargs['pk'])
form_class = self.get_form_class()
form = self.get_form(form_class)
form_framework = SkillFrameworkFormSet(self.request.POST)
form_language = SkillPLanguageFormSet(self.request.POST)
if (form.is_valid() and form_framework.is_valid() and
form_language.is_valid()):
return self.form_valid(form, form_framework, form_language)
else:
return self.form_invalid(form, form_framework, form_language)
def form_valid(self, form, form_framework, form_language):
"""
Called if all forms are valid. Creates a Employee instance along with
associated models and then redirects to a
success page.
"""
self.object = form.save()
form_framework.instance = self.object
form_framework.save()
form_language.instance = self.object
form_language.save()
return HttpResponseRedirect(reverse_lazy('profile', args=[self.kwargs['pk']]))
def form_invalid(self, form, form_framework, form_language):
"""
Called if a form is invalid. Re-renders the context data with the
data-filled forms and errors.
"""
return self.render_to_response(
self.get_context_data(form=form,
form_framework=form_framework,
form_language=form_language,
))
在管理员窗格中,我创建了Techgroup模型的两个实例:
-框架
-编程语言
所有技能模型都属于两组中的一组。在前面,我显示了两个表单,一个包含queryset,其实例属于框架,另一个包含编程语言的实例。
我使用ModelsForm划分查询集:
forms.py
class Skill(models.Model):
employee = models.ForeignKey(
Employee, on_delete=models.CASCADE, related_name="employee_skills")
technology = models.ForeignKey(Technology, on_delete=models.CASCADE)
year = models.CharField('common year using amount ', max_length=4)
last_year = models.CharField('Last year of technology using ', max_length=4)
level = models.CharField("experience level", max_length=64, choices=LEVELS)
class Techgroup(models.Model):
""" Group of technology """
name = models.CharField('group_name', max_length=32, unique=True)
class Technology(models.Model):
"""Technologies."""
name = models.CharField('technology name', max_length=32, unique=True)
group = models.ForeignKey(Techgroup, on_delete=models.CASCADE, related_name="group")
class SkillBaseCreateForm(forms.ModelForm):
YEAR_CHOICES = [(r, r) for r in range(1, 11)]
LAST_YEAR_CHOICES = [(r, r) for r in range(2015, datetime.datetime.now().year + 1)]
year = forms.CharField(
widget=forms.Select(choices=YEAR_CHOICES),
)
last_year = forms.CharField(widget=forms.Select(choices=LAST_YEAR_CHOICES))
class Meta:
model = Skill
fields = ['technology', 'level', 'last_year', 'year']
class SkillCreatePLanguageForm(SkillBaseCreateForm):
def __init__(self, *args, **kwargs):
super(SkillCreatePLanguageForm, self).__init__(*args, **kwargs)
self.fields['technology'].queryset = Technology.objects.filter(group__name="Programming language")
class SkillCreateFrameworkForm(SkillBaseCreateForm):
def __init__(self, *args, **kwargs):
super(SkillCreateFrameworkForm, self).__init__(*args, **kwargs)
self.fields['technology'].queryset = Technology.objects.filter(group__name="Framework")
SkillFrameworkFormSet = inlineformset_factory(Employee, Skill, form=SkillCreateFrameworkForm, extra=1, can_delete=False)
SkillPLanguageFormSet = inlineformset_factory(Employee, Skill, form=SkillCreatePLanguageForm, extra=1, can_delete=False)
class SkillTestCreateView(AuthorizedMixin, CreateView):
"""
Create new skill instances
"""
template_name = 'edit.html'
model = Employee
form_class = EmployeeEditForm
def get(self, *args, **kwargs):
"""
Handles GET requests and instantiates blank versions of the form
and its inline formsets.
"""
self.object = Employee.objects.get(pk=self.kwargs['pk'])
form_class = self.get_form_class()
form = self.get_form(form_class)
form_framework = SkillFrameworkFormSet()
form_language = SkillPLanguageFormSet()
return self.render_to_response(
self.get_context_data(form=form,
form_framework=form_framework,
form_language=form_language))
def post(self, request, *args, **kwargs):
"""
Handles POST requests, instantiating a form instance and its inline
formsets with the passed POST variables and then checking them for
validity.
"""
self.object = Employee.objects.get(pk=self.kwargs['pk'])
form_class = self.get_form_class()
form = self.get_form(form_class)
form_framework = SkillFrameworkFormSet(self.request.POST)
form_language = SkillPLanguageFormSet(self.request.POST)
if (form.is_valid() and form_framework.is_valid() and
form_language.is_valid()):
return self.form_valid(form, form_framework, form_language)
else:
return self.form_invalid(form, form_framework, form_language)
def form_valid(self, form, form_framework, form_language):
"""
Called if all forms are valid. Creates a Employee instance along with
associated models and then redirects to a
success page.
"""
self.object = form.save()
form_framework.instance = self.object
form_framework.save()
form_language.instance = self.object
form_language.save()
return HttpResponseRedirect(reverse_lazy('profile', args=[self.kwargs['pk']]))
def form_invalid(self, form, form_framework, form_language):
"""
Called if a form is invalid. Re-renders the context data with the
data-filled forms and errors.
"""
return self.render_to_response(
self.get_context_data(form=form,
form_framework=form_framework,
form_language=form_language,
))
视图.py
class Skill(models.Model):
employee = models.ForeignKey(
Employee, on_delete=models.CASCADE, related_name="employee_skills")
technology = models.ForeignKey(Technology, on_delete=models.CASCADE)
year = models.CharField('common year using amount ', max_length=4)
last_year = models.CharField('Last year of technology using ', max_length=4)
level = models.CharField("experience level", max_length=64, choices=LEVELS)
class Techgroup(models.Model):
""" Group of technology """
name = models.CharField('group_name', max_length=32, unique=True)
class Technology(models.Model):
"""Technologies."""
name = models.CharField('technology name', max_length=32, unique=True)
group = models.ForeignKey(Techgroup, on_delete=models.CASCADE, related_name="group")
class SkillBaseCreateForm(forms.ModelForm):
YEAR_CHOICES = [(r, r) for r in range(1, 11)]
LAST_YEAR_CHOICES = [(r, r) for r in range(2015, datetime.datetime.now().year + 1)]
year = forms.CharField(
widget=forms.Select(choices=YEAR_CHOICES),
)
last_year = forms.CharField(widget=forms.Select(choices=LAST_YEAR_CHOICES))
class Meta:
model = Skill
fields = ['technology', 'level', 'last_year', 'year']
class SkillCreatePLanguageForm(SkillBaseCreateForm):
def __init__(self, *args, **kwargs):
super(SkillCreatePLanguageForm, self).__init__(*args, **kwargs)
self.fields['technology'].queryset = Technology.objects.filter(group__name="Programming language")
class SkillCreateFrameworkForm(SkillBaseCreateForm):
def __init__(self, *args, **kwargs):
super(SkillCreateFrameworkForm, self).__init__(*args, **kwargs)
self.fields['technology'].queryset = Technology.objects.filter(group__name="Framework")
SkillFrameworkFormSet = inlineformset_factory(Employee, Skill, form=SkillCreateFrameworkForm, extra=1, can_delete=False)
SkillPLanguageFormSet = inlineformset_factory(Employee, Skill, form=SkillCreatePLanguageForm, extra=1, can_delete=False)
class SkillTestCreateView(AuthorizedMixin, CreateView):
"""
Create new skill instances
"""
template_name = 'edit.html'
model = Employee
form_class = EmployeeEditForm
def get(self, *args, **kwargs):
"""
Handles GET requests and instantiates blank versions of the form
and its inline formsets.
"""
self.object = Employee.objects.get(pk=self.kwargs['pk'])
form_class = self.get_form_class()
form = self.get_form(form_class)
form_framework = SkillFrameworkFormSet()
form_language = SkillPLanguageFormSet()
return self.render_to_response(
self.get_context_data(form=form,
form_framework=form_framework,
form_language=form_language))
def post(self, request, *args, **kwargs):
"""
Handles POST requests, instantiating a form instance and its inline
formsets with the passed POST variables and then checking them for
validity.
"""
self.object = Employee.objects.get(pk=self.kwargs['pk'])
form_class = self.get_form_class()
form = self.get_form(form_class)
form_framework = SkillFrameworkFormSet(self.request.POST)
form_language = SkillPLanguageFormSet(self.request.POST)
if (form.is_valid() and form_framework.is_valid() and
form_language.is_valid()):
return self.form_valid(form, form_framework, form_language)
else:
return self.form_invalid(form, form_framework, form_language)
def form_valid(self, form, form_framework, form_language):
"""
Called if all forms are valid. Creates a Employee instance along with
associated models and then redirects to a
success page.
"""
self.object = form.save()
form_framework.instance = self.object
form_framework.save()
form_language.instance = self.object
form_language.save()
return HttpResponseRedirect(reverse_lazy('profile', args=[self.kwargs['pk']]))
def form_invalid(self, form, form_framework, form_language):
"""
Called if a form is invalid. Re-renders the context data with the
data-filled forms and errors.
"""
return self.render_to_response(
self.get_context_data(form=form,
form_framework=form_framework,
form_language=form_language,
))
问题是我在提交表单时总是收到错误消息:
Select a valid choice. That choice is not one of the available choices.
问题是,当我提交表单时,我总是在queryset的技术字段中收到一条错误消息,该消息首先显示在模板中。
也就是说,如果模板
{form_framework}}
{form_language}
错误
queryset = Technology.objects.filter(group__name="Framework"
如果
错误
queryset = Technology.objects.filter(group__name="Programming language"
如果我在views.py中只留下一个表单,那么一切都开始工作了
我已经想了两天了,我想我已经走到了死胡同了。需要帮助