提交时手动渲染Django formset重定向问题
Manually rendered Django formset redirection problem at submition
我定义了以下模型:
class Item(models.Model):
rfid_tag = models.CharField()
asset = models.OneToOneField('Assets', default=None, null=True,
on_delete=models.SET_DEFAULT,)
date = models.DateTimeField(name='timestamp',
auto_now_add=True,)
...
class Assets(models.Model):
id = models.AutoField(db_column='Id', primary_key=True)
assettag = models.CharField(db_column='AssetTag', unique=True, max_length=10)
assettype = models.CharField(db_column='AssetType', max_length=150)
...
class Meta:
managed = False
db_table = 'Assets'
ordering = ['assettag']
def __str__(self):
return f"{self.assettag}"
def __unicode__(self):
return f"{self.assettag}"
为此我创建了以下表单和表单集:
class ItemDeleteForm(forms.ModelForm):
asset = forms.CharField(required=True,
help_text= "Item asset tag",
max_length=16,
label="AssetTag",
disabled=True,
)
delete = forms.BooleanField(required=False,
label="Delete",
help_text='Check this box to delete the corresponding item',
)
class Meta:
model = Item
fields = ['asset']
ItemDeleteMultiple = forms.modelformset_factory(model=Item,
form=ItemDeleteForm,
extra=0,
)
由视图管理:
class DeleteMultipleView(generic.FormView):
template_name = '*some html file*'
form_class = ItemDeleteMultiple
success_url = reverse_lazy('*app_name:url_name*')
def form_valid(self, form):
return super().form_valid(form)
并在模板中呈现:
{% extends "pages/base.html" %}
{% block title %}
<title>Delete Multiple</title>
{% endblock %}
{% block content %}
<h1>Delete Multiple Items</h1>
<br>
<form class="ManualForm" action ="." method="POST"> {% csrf_token %}
{{ form.management_form }}
<table border="2">
<tr><th colspan="3" scope="row">Select Items to Delete</th></tr>
{% for item_form in form %}
<tr>
<td><label for="{{ item_form.asset.id_for_label }}">AssetTag {{forloop.counter}}:</label>
{% if item_form.non_field_errors %}
{{ item_form.non_field_errors }}
{% endif %}
{% if item_form.asset.errors %}
{{item_form.asset.errors}}
{% endif %}
</td>
<td>{{item_form.asset}}</td>
<td>{{item_form.delete}}
{% if item_form.delete.errors %}
{{item_form.delete.errors}}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
<br>
<input class = "btn btn-success" type="submit" value="Delete Selected" />
<a href="{% url 'inventory:index' %}" class="btn btn-secondary">Cancel</a>
</form>
<form class="AutoForm" action ="." method="POST"> {% csrf_token %}
{{form.as_table}}
<input class = "btn btn-success" type="submit" value="Delete Selected" />
<a href="{% url 'inventory:index' %}" class="btn btn-secondary">Cancel</a>
</form>
{% endblock %}
当我提交 AutoForm 时,一切都很好。它会将我带到 app_name:url_name
,但如果我提交 ManualForm,我不会被重定向。它将简单地清除所有数据并重新加载带有空字段的表单页面。
AutoForm 的 HTTP POST 响应状态代码是 302,而 ManualForm 是 200。
我不明白模板如何影响 url 重定向的行为。我在表单集的手动渲染中做错了什么?
好像加了:
{% for field in item_form.hidden_fields %}
{{field}}
{% endfor %}
下 {% for item_form in form %}
将解决问题。
我对docs不是很了解:
Looping over hidden and visible fields
If you’re manually laying out a form in a template, as opposed to
relying on Django’s default form layout, you might want to treat
< input type="hidden"> fields differently from non-hidden fields. For
example, because hidden fields don’t display anything, putting error
messages “next to” the field could cause confusion for your users – so
errors for those fields should be handled differently.
我只是觉得这是关于错误的,所以我没有在意。但是它说的关于表单的第一件事是:
As an example, the login form for the Django admin contains several
< input> elements: one of type="text" for the username, one of
type="password" for the password, and one of type="submit" for the
“Log in” button. It also contains some hidden text fields that the
user doesn’t see, which Django uses to determine what to do next.
It also tells the browser that the form data should be sent to the URL
specified in the < form>’s action attribute - /admin/ - and that it
should be sent using the HTTP mechanism specified by the method
attribute - post.
也许它会对其他人有所帮助。
我定义了以下模型:
class Item(models.Model):
rfid_tag = models.CharField()
asset = models.OneToOneField('Assets', default=None, null=True,
on_delete=models.SET_DEFAULT,)
date = models.DateTimeField(name='timestamp',
auto_now_add=True,)
...
class Assets(models.Model):
id = models.AutoField(db_column='Id', primary_key=True)
assettag = models.CharField(db_column='AssetTag', unique=True, max_length=10)
assettype = models.CharField(db_column='AssetType', max_length=150)
...
class Meta:
managed = False
db_table = 'Assets'
ordering = ['assettag']
def __str__(self):
return f"{self.assettag}"
def __unicode__(self):
return f"{self.assettag}"
为此我创建了以下表单和表单集:
class ItemDeleteForm(forms.ModelForm):
asset = forms.CharField(required=True,
help_text= "Item asset tag",
max_length=16,
label="AssetTag",
disabled=True,
)
delete = forms.BooleanField(required=False,
label="Delete",
help_text='Check this box to delete the corresponding item',
)
class Meta:
model = Item
fields = ['asset']
ItemDeleteMultiple = forms.modelformset_factory(model=Item,
form=ItemDeleteForm,
extra=0,
)
由视图管理:
class DeleteMultipleView(generic.FormView):
template_name = '*some html file*'
form_class = ItemDeleteMultiple
success_url = reverse_lazy('*app_name:url_name*')
def form_valid(self, form):
return super().form_valid(form)
并在模板中呈现:
{% extends "pages/base.html" %}
{% block title %}
<title>Delete Multiple</title>
{% endblock %}
{% block content %}
<h1>Delete Multiple Items</h1>
<br>
<form class="ManualForm" action ="." method="POST"> {% csrf_token %}
{{ form.management_form }}
<table border="2">
<tr><th colspan="3" scope="row">Select Items to Delete</th></tr>
{% for item_form in form %}
<tr>
<td><label for="{{ item_form.asset.id_for_label }}">AssetTag {{forloop.counter}}:</label>
{% if item_form.non_field_errors %}
{{ item_form.non_field_errors }}
{% endif %}
{% if item_form.asset.errors %}
{{item_form.asset.errors}}
{% endif %}
</td>
<td>{{item_form.asset}}</td>
<td>{{item_form.delete}}
{% if item_form.delete.errors %}
{{item_form.delete.errors}}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
<br>
<input class = "btn btn-success" type="submit" value="Delete Selected" />
<a href="{% url 'inventory:index' %}" class="btn btn-secondary">Cancel</a>
</form>
<form class="AutoForm" action ="." method="POST"> {% csrf_token %}
{{form.as_table}}
<input class = "btn btn-success" type="submit" value="Delete Selected" />
<a href="{% url 'inventory:index' %}" class="btn btn-secondary">Cancel</a>
</form>
{% endblock %}
当我提交 AutoForm 时,一切都很好。它会将我带到 app_name:url_name
,但如果我提交 ManualForm,我不会被重定向。它将简单地清除所有数据并重新加载带有空字段的表单页面。
AutoForm 的 HTTP POST 响应状态代码是 302,而 ManualForm 是 200。
我不明白模板如何影响 url 重定向的行为。我在表单集的手动渲染中做错了什么?
好像加了:
{% for field in item_form.hidden_fields %}
{{field}}
{% endfor %}
下 {% for item_form in form %}
将解决问题。
我对docs不是很了解:
Looping over hidden and visible fields
If you’re manually laying out a form in a template, as opposed to relying on Django’s default form layout, you might want to treat < input type="hidden"> fields differently from non-hidden fields. For example, because hidden fields don’t display anything, putting error messages “next to” the field could cause confusion for your users – so errors for those fields should be handled differently.
我只是觉得这是关于错误的,所以我没有在意。但是它说的关于表单的第一件事是:
As an example, the login form for the Django admin contains several < input> elements: one of type="text" for the username, one of type="password" for the password, and one of type="submit" for the “Log in” button. It also contains some hidden text fields that the user doesn’t see, which Django uses to determine what to do next.
It also tells the browser that the form data should be sent to the URL specified in the < form>’s action attribute - /admin/ - and that it should be sent using the HTTP mechanism specified by the method attribute - post.
也许它会对其他人有所帮助。