我在显示带有多个实例对象的内联formset时遇到问题。我想要一个所有Owner
的列表以及所有Pet
的内联formset,所有这一页都是一页。
下面的代码可以工作,但一次只能调用1个所有者对象。有什么建议吗?
的新问题models.py
class Teacher(models.Model):
teacher = models.CharField(max_length=300)
class Owner(models.Model):
relevantteacher = models.ForeignKey(Teacher)
owner = models.CharField(max_length=300)
class PetName(models.Model):
relevantowner = models.ForeignKey(Owner)
pet_name = models.CharField(max_length=50)
forms.py
class OwnerForm(forms.ModelForm):
class Meta:
model = Owner
PetNameFormSet = inlineformset_factory(Owner,
PetName,
can_delete=False,
extra=3,
form=OwnerForm)
views.py
def petname(request, teacher_id):
teacher = get_object_or_404(Teacher, pk=teacher_id)
owners = Owner.objects.filter(relevantteacher=teacher_id)
owner = owners[0]
if request.method == "POST":
petNameInlineFormSet = PetNameFormSet(request.POST, request.FILES, instance=owner)
if petNameInlineFormSet.is_valid():
petNameInlineFormSet.save()
return HttpResponseRedirect(reverse('success'))
else:
petNameInlineFormSet = PetNameFormSet(instance=owner)
context = {'teacher': teacher, 'owner': owner, 'petNameInlineFormSet' : petNameInlineFormSet}
return render(request, 'petname.html', context)
HTML petname.html
{% load url from future %}
<form class="petname_form" action="{% url "petname" teacher.id %}" method="post">{% csrf_token %}
{{ teacher }}
{{ owner.as_table }}
{{ petNameInlineFormSet.as_table }}
</form>
更新
HTML
{% for owner_form in owner_forms %}
<form class="petname_form" action="{% url "petname" teacher.id %}" method="post">{% csrf_token %
{% for o in owners %}
{{o.owner}} has pets:<br/> //owner is the PK of the Owner model
{{ owner_forms.relevantteacher }}
{{ owner_forms.as_table }}
{{ owner_forms.inline_form.as_table }}
{% endfor %}
</form>
答案 0 :(得分:1)
基本上,您需要做的是编译要呈现的所有者表单列表。验证后,您必须保留每个表单的错误和成功消息,并呈现结果。
这是一个基于views.py实现上述内容的半伪代码示例:
owner_forms = []
if request.method == "POST":
for owner in owners:
#passing instance here may yeild unexpected behavior; django is aware of instance based on request.POST data.
owner_form = PetNameFormSet(request.POST, request.FILES)
owner_forms.append(owner_form)
if petNameInlineFormSet.is_valid():
petNameInlineFormSet.save()
else:
for owner in owners:
owner_form = PetNameFormSet(instance=owner)
owner_forms.append(owner_form)
context['owner_forms'] = owner_forms
现在,在owner_forms中呈现每个表单:
{% for owner_form in owner_forms %}
<form class="petname_form" action="{% url "petname" teacher.id %}" method="post">{% csrf_token %}
{% refer to the teacher object associated with the object the form is generated on %}
{{ owner_form.relevantteacher }}
{{ owner_form.as_table }}
{{ owner_form.inline_form.as_table }}
</form>
{% endfor %}
其他建议:
max_length=300
存在问题。一般的经验法则是将CharField限制为255个字符。大于255的任何内容都应该是TextField。models.ForeignKey(Model)
替换models.ForeignKey("Model")
的实例,以防止将来出现潜在的竞争条件。