浏览代码

Fixed #29375 -- Removed empty action attribute on HTML forms.

CHI Cheng 7 年之前
父节点
当前提交
4660ce5a69

+ 4 - 4
docs/ref/class-based-views/generic-editing.txt

@@ -74,7 +74,7 @@ editing content:
 
 
     .. code-block:: html+django
     .. code-block:: html+django
 
 
-        <form action="" method="post">{% csrf_token %}
+        <form method="post">{% csrf_token %}
             {{ form.as_p }}
             {{ form.as_p }}
             <input type="submit" value="Send message">
             <input type="submit" value="Send message">
         </form>
         </form>
@@ -130,7 +130,7 @@ editing content:
 
 
     .. code-block:: html+django
     .. code-block:: html+django
 
 
-        <form action="" method="post">{% csrf_token %}
+        <form method="post">{% csrf_token %}
             {{ form.as_p }}
             {{ form.as_p }}
             <input type="submit" value="Save">
             <input type="submit" value="Save">
         </form>
         </form>
@@ -187,7 +187,7 @@ editing content:
 
 
     .. code-block:: html+django
     .. code-block:: html+django
 
 
-        <form action="" method="post">{% csrf_token %}
+        <form method="post">{% csrf_token %}
             {{ form.as_p }}
             {{ form.as_p }}
             <input type="submit" value="Update">
             <input type="submit" value="Update">
         </form>
         </form>
@@ -238,7 +238,7 @@ editing content:
 
 
     .. code-block:: html+django
     .. code-block:: html+django
 
 
-        <form action="" method="post">{% csrf_token %}
+        <form method="post">{% csrf_token %}
             <p>Are you sure you want to delete "{{ object }}"?</p>
             <p>Are you sure you want to delete "{{ object }}"?</p>
             <input type="submit" value="Confirm">
             <input type="submit" value="Confirm">
         </form>
         </form>

+ 2 - 2
docs/ref/csrf.txt

@@ -41,7 +41,7 @@ To take advantage of CSRF protection in your views, follow these steps:
 
 
    .. code-block:: html+django
    .. code-block:: html+django
 
 
-       <form action="" method="post">{% csrf_token %}
+       <form method="post">{% csrf_token %}
 
 
    This should not be done for POST forms that target external URLs, since
    This should not be done for POST forms that target external URLs, since
    that would cause the CSRF token to be leaked, leading to a vulnerability.
    that would cause the CSRF token to be leaked, leading to a vulnerability.
@@ -179,7 +179,7 @@ to ``{% csrf_token %}`` in the Django template language. For example:
 
 
 .. code-block:: html+jinja
 .. code-block:: html+jinja
 
 
-    <form action="" method="post">{{ csrf_input }}
+    <form method="post">{{ csrf_input }}
 
 
 The decorator method
 The decorator method
 --------------------
 --------------------

+ 3 - 3
docs/topics/forms/formsets.txt

@@ -630,7 +630,7 @@ The ``manage_articles.html`` template might look like this:
 
 
 .. code-block:: html+django
 .. code-block:: html+django
 
 
-    <form method="post" action="">
+    <form method="post">
         {{ formset.management_form }}
         {{ formset.management_form }}
         <table>
         <table>
             {% for form in formset %}
             {% for form in formset %}
@@ -644,7 +644,7 @@ deal with the management form:
 
 
 .. code-block:: html+django
 .. code-block:: html+django
 
 
-    <form method="post" action="">
+    <form method="post">
         <table>
         <table>
             {{ formset }}
             {{ formset }}
         </table>
         </table>
@@ -662,7 +662,7 @@ If you manually render fields in the template, you can render
 
 
 .. code-block:: html+django
 .. code-block:: html+django
 
 
-    <form method="post" action="">
+    <form method="post">
         {{ formset.management_form }}
         {{ formset.management_form }}
         {% for form in formset %}
         {% for form in formset %}
             <ul>
             <ul>

+ 4 - 4
docs/topics/forms/modelforms.txt

@@ -1071,14 +1071,14 @@ There are three ways to render a formset in a Django template.
 
 
 First, you can let the formset do most of the work::
 First, you can let the formset do most of the work::
 
 
-    <form method="post" action="">
+    <form method="post">
         {{ formset }}
         {{ formset }}
     </form>
     </form>
 
 
 Second, you can manually render the formset, but let the form deal with
 Second, you can manually render the formset, but let the form deal with
 itself::
 itself::
 
 
-    <form method="post" action="">
+    <form method="post">
         {{ formset.management_form }}
         {{ formset.management_form }}
         {% for form in formset %}
         {% for form in formset %}
             {{ form }}
             {{ form }}
@@ -1091,7 +1091,7 @@ form as shown above. See the :ref:`management form documentation
 
 
 Third, you can manually render each field::
 Third, you can manually render each field::
 
 
-    <form method="post" action="">
+    <form method="post">
         {{ formset.management_form }}
         {{ formset.management_form }}
         {% for form in formset %}
         {% for form in formset %}
             {% for field in form %}
             {% for field in form %}
@@ -1104,7 +1104,7 @@ If you opt to use this third method and you don't iterate over the fields with
 a ``{% for %}`` loop, you'll need to render the primary key field. For example,
 a ``{% for %}`` loop, you'll need to render the primary key field. For example,
 if you were rendering the ``name`` and ``age`` fields of a model::
 if you were rendering the ``name`` and ``age`` fields of a model::
 
 
-    <form method="post" action="">
+    <form method="post">
         {{ formset.management_form }}
         {{ formset.management_form }}
         {% for form in formset %}
         {% for form in formset %}
             {{ form.id }}
             {{ form.id }}

+ 1 - 1
tests/forms_tests/templates/forms_tests/article_form.html

@@ -1,6 +1,6 @@
 <html>
 <html>
 <body>
 <body>
-  <form method="post" action="">{% csrf_token %}
+  <form method="post">{% csrf_token %}
     {{ form.as_p }}<br>
     {{ form.as_p }}<br>
     <input id="submit" type="submit">
     <input id="submit" type="submit">
   </form>
   </form>

+ 17 - 17
tests/forms_tests/tests/test_forms.py

@@ -2482,13 +2482,13 @@ Password: <input type="password" name="password" required>
                 return 'VALID: %r' % sorted(form.cleaned_data.items())
                 return 'VALID: %r' % sorted(form.cleaned_data.items())
 
 
             t = Template(
             t = Template(
-                '<form action="" method="post">\n'
+                '<form method="post">\n'
                 '<table>\n{{ form }}\n</table>\n<input type="submit" required>\n</form>'
                 '<table>\n{{ form }}\n</table>\n<input type="submit" required>\n</form>'
             )
             )
             return t.render(Context({'form': form}))
             return t.render(Context({'form': form}))
 
 
         # Case 1: GET (an empty form, with no errors).)
         # Case 1: GET (an empty form, with no errors).)
-        self.assertHTMLEqual(my_function('GET', {}), """<form action="" method="post">
+        self.assertHTMLEqual(my_function('GET', {}), """<form method="post">
 <table>
 <table>
 <tr><th>Username:</th><td><input type="text" name="username" maxlength="10" required></td></tr>
 <tr><th>Username:</th><td><input type="text" name="username" maxlength="10" required></td></tr>
 <tr><th>Password1:</th><td><input type="password" name="password1" required></td></tr>
 <tr><th>Password1:</th><td><input type="password" name="password1" required></td></tr>
@@ -2499,7 +2499,7 @@ Password: <input type="password" name="password" required>
         # Case 2: POST with erroneous data (a redisplayed form, with errors).)
         # Case 2: POST with erroneous data (a redisplayed form, with errors).)
         self.assertHTMLEqual(
         self.assertHTMLEqual(
             my_function('POST', {'username': 'this-is-a-long-username', 'password1': 'foo', 'password2': 'bar'}),
             my_function('POST', {'username': 'this-is-a-long-username', 'password1': 'foo', 'password2': 'bar'}),
-            """<form action="" method="post">
+            """<form method="post">
 <table>
 <table>
 <tr><td colspan="2"><ul class="errorlist nonfield"><li>Please make sure your passwords match.</li></ul></td></tr>
 <tr><td colspan="2"><ul class="errorlist nonfield"><li>Please make sure your passwords match.</li></ul></td></tr>
 <tr><th>Username:</th><td><ul class="errorlist">
 <tr><th>Username:</th><td><ul class="errorlist">
@@ -2535,13 +2535,13 @@ Password: <input type="password" name="password" required>
         # fields. Note, however, that this flexibility comes with the responsibility of
         # fields. Note, however, that this flexibility comes with the responsibility of
         # displaying all the errors, including any that might not be associated with a
         # displaying all the errors, including any that might not be associated with a
         # particular field.
         # particular field.
-        t = Template('''<form action="">
+        t = Template('''<form>
 {{ form.username.errors.as_ul }}<p><label>Your username: {{ form.username }}</label></p>
 {{ form.username.errors.as_ul }}<p><label>Your username: {{ form.username }}</label></p>
 {{ form.password1.errors.as_ul }}<p><label>Password: {{ form.password1 }}</label></p>
 {{ form.password1.errors.as_ul }}<p><label>Password: {{ form.password1 }}</label></p>
 {{ form.password2.errors.as_ul }}<p><label>Password (again): {{ form.password2 }}</label></p>
 {{ form.password2.errors.as_ul }}<p><label>Password (again): {{ form.password2 }}</label></p>
 <input type="submit" required>
 <input type="submit" required>
 </form>''')
 </form>''')
-        self.assertHTMLEqual(t.render(Context({'form': UserRegistration(auto_id=False)})), """<form action="">
+        self.assertHTMLEqual(t.render(Context({'form': UserRegistration(auto_id=False)})), """<form>
 <p><label>Your username: <input type="text" name="username" maxlength="10" required></label></p>
 <p><label>Your username: <input type="text" name="username" maxlength="10" required></label></p>
 <p><label>Password: <input type="password" name="password1" required></label></p>
 <p><label>Password: <input type="password" name="password1" required></label></p>
 <p><label>Password (again): <input type="password" name="password2" required></label></p>
 <p><label>Password (again): <input type="password" name="password2" required></label></p>
@@ -2549,7 +2549,7 @@ Password: <input type="password" name="password" required>
 </form>""")
 </form>""")
         self.assertHTMLEqual(
         self.assertHTMLEqual(
             t.render(Context({'form': UserRegistration({'username': 'django'}, auto_id=False)})),
             t.render(Context({'form': UserRegistration({'username': 'django'}, auto_id=False)})),
-            """<form action="">
+            """<form>
 <p><label>Your username: <input type="text" name="username" value="django" maxlength="10" required></label></p>
 <p><label>Your username: <input type="text" name="username" value="django" maxlength="10" required></label></p>
 <ul class="errorlist"><li>This field is required.</li></ul><p>
 <ul class="errorlist"><li>This field is required.</li></ul><p>
 <label>Password: <input type="password" name="password1" required></label></p>
 <label>Password: <input type="password" name="password1" required></label></p>
@@ -2563,13 +2563,13 @@ Password: <input type="password" name="password" required>
         # a field by using the 'label' argument to a Field class. If you don't specify
         # a field by using the 'label' argument to a Field class. If you don't specify
         # 'label', Django will use the field name with underscores converted to spaces,
         # 'label', Django will use the field name with underscores converted to spaces,
         # and the initial letter capitalized.
         # and the initial letter capitalized.
-        t = Template('''<form action="">
+        t = Template('''<form>
 <p><label>{{ form.username.label }}: {{ form.username }}</label></p>
 <p><label>{{ form.username.label }}: {{ form.username }}</label></p>
 <p><label>{{ form.password1.label }}: {{ form.password1 }}</label></p>
 <p><label>{{ form.password1.label }}: {{ form.password1 }}</label></p>
 <p><label>{{ form.password2.label }}: {{ form.password2 }}</label></p>
 <p><label>{{ form.password2.label }}: {{ form.password2 }}</label></p>
 <input type="submit" required>
 <input type="submit" required>
 </form>''')
 </form>''')
-        self.assertHTMLEqual(t.render(Context({'form': UserRegistration(auto_id=False)})), """<form action="">
+        self.assertHTMLEqual(t.render(Context({'form': UserRegistration(auto_id=False)})), """<form>
 <p><label>Username: <input type="text" name="username" maxlength="10" required></label></p>
 <p><label>Username: <input type="text" name="username" maxlength="10" required></label></p>
 <p><label>Password1: <input type="password" name="password1" required></label></p>
 <p><label>Password1: <input type="password" name="password1" required></label></p>
 <p><label>Password2: <input type="password" name="password2" required></label></p>
 <p><label>Password2: <input type="password" name="password2" required></label></p>
@@ -2580,19 +2580,19 @@ Password: <input type="password" name="password" required>
         # wrapped around it, but *only* if the given field has an "id" attribute.
         # wrapped around it, but *only* if the given field has an "id" attribute.
         # Recall from above that passing the "auto_id" argument to a Form gives each
         # Recall from above that passing the "auto_id" argument to a Form gives each
         # field an "id" attribute.
         # field an "id" attribute.
-        t = Template('''<form action="">
+        t = Template('''<form>
 <p>{{ form.username.label_tag }} {{ form.username }}</p>
 <p>{{ form.username.label_tag }} {{ form.username }}</p>
 <p>{{ form.password1.label_tag }} {{ form.password1 }}</p>
 <p>{{ form.password1.label_tag }} {{ form.password1 }}</p>
 <p>{{ form.password2.label_tag }} {{ form.password2 }}</p>
 <p>{{ form.password2.label_tag }} {{ form.password2 }}</p>
 <input type="submit" required>
 <input type="submit" required>
 </form>''')
 </form>''')
-        self.assertHTMLEqual(t.render(Context({'form': UserRegistration(auto_id=False)})), """<form action="">
+        self.assertHTMLEqual(t.render(Context({'form': UserRegistration(auto_id=False)})), """<form>
 <p>Username: <input type="text" name="username" maxlength="10" required></p>
 <p>Username: <input type="text" name="username" maxlength="10" required></p>
 <p>Password1: <input type="password" name="password1" required></p>
 <p>Password1: <input type="password" name="password1" required></p>
 <p>Password2: <input type="password" name="password2" required></p>
 <p>Password2: <input type="password" name="password2" required></p>
 <input type="submit" required>
 <input type="submit" required>
 </form>""")
 </form>""")
-        self.assertHTMLEqual(t.render(Context({'form': UserRegistration(auto_id='id_%s')})), """<form action="">
+        self.assertHTMLEqual(t.render(Context({'form': UserRegistration(auto_id='id_%s')})), """<form>
 <p><label for="id_username">Username:</label>
 <p><label for="id_username">Username:</label>
 <input id="id_username" type="text" name="username" maxlength="10" required></p>
 <input id="id_username" type="text" name="username" maxlength="10" required></p>
 <p><label for="id_password1">Password1:</label>
 <p><label for="id_password1">Password1:</label>
@@ -2604,7 +2604,7 @@ Password: <input type="password" name="password" required>
 
 
         # User form.[field].help_text to output a field's help text. If the given field
         # User form.[field].help_text to output a field's help text. If the given field
         # does not have help text, nothing will be output.
         # does not have help text, nothing will be output.
-        t = Template('''<form action="">
+        t = Template('''<form>
 <p>{{ form.username.label_tag }} {{ form.username }}<br>{{ form.username.help_text }}</p>
 <p>{{ form.username.label_tag }} {{ form.username }}<br>{{ form.username.help_text }}</p>
 <p>{{ form.password1.label_tag }} {{ form.password1 }}</p>
 <p>{{ form.password1.label_tag }} {{ form.password1 }}</p>
 <p>{{ form.password2.label_tag }} {{ form.password2 }}</p>
 <p>{{ form.password2.label_tag }} {{ form.password2 }}</p>
@@ -2612,7 +2612,7 @@ Password: <input type="password" name="password" required>
 </form>''')
 </form>''')
         self.assertHTMLEqual(
         self.assertHTMLEqual(
             t.render(Context({'form': UserRegistration(auto_id=False)})),
             t.render(Context({'form': UserRegistration(auto_id=False)})),
-            """<form action="">
+            """<form>
 <p>Username: <input type="text" name="username" maxlength="10" required><br>
 <p>Username: <input type="text" name="username" maxlength="10" required><br>
 Good luck picking a username that doesn&#39;t already exist.</p>
 Good luck picking a username that doesn&#39;t already exist.</p>
 <p>Password1: <input type="password" name="password1" required></p>
 <p>Password1: <input type="password" name="password1" required></p>
@@ -2629,7 +2629,7 @@ Good luck picking a username that doesn&#39;t already exist.</p>
         # the errors caused by Form.clean() -- use {{ form.non_field_errors }} in the
         # the errors caused by Form.clean() -- use {{ form.non_field_errors }} in the
         # template. If used on its own, it is displayed as a <ul> (or an empty string, if
         # template. If used on its own, it is displayed as a <ul> (or an empty string, if
         # the list of errors is empty). You can also use it in {% if %} statements.
         # the list of errors is empty). You can also use it in {% if %} statements.
-        t = Template('''<form action="">
+        t = Template('''<form>
 {{ form.username.errors.as_ul }}<p><label>Your username: {{ form.username }}</label></p>
 {{ form.username.errors.as_ul }}<p><label>Your username: {{ form.username }}</label></p>
 {{ form.password1.errors.as_ul }}<p><label>Password: {{ form.password1 }}</label></p>
 {{ form.password1.errors.as_ul }}<p><label>Password: {{ form.password1 }}</label></p>
 {{ form.password2.errors.as_ul }}<p><label>Password (again): {{ form.password2 }}</label></p>
 {{ form.password2.errors.as_ul }}<p><label>Password (again): {{ form.password2 }}</label></p>
@@ -2639,14 +2639,14 @@ Good luck picking a username that doesn&#39;t already exist.</p>
             t.render(Context({
             t.render(Context({
                 'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
                 'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
             })),
             })),
-            """<form action="">
+            """<form>
 <p><label>Your username: <input type="text" name="username" value="django" maxlength="10" required></label></p>
 <p><label>Your username: <input type="text" name="username" value="django" maxlength="10" required></label></p>
 <p><label>Password: <input type="password" name="password1" required></label></p>
 <p><label>Password: <input type="password" name="password1" required></label></p>
 <p><label>Password (again): <input type="password" name="password2" required></label></p>
 <p><label>Password (again): <input type="password" name="password2" required></label></p>
 <input type="submit" required>
 <input type="submit" required>
 </form>"""
 </form>"""
         )
         )
-        t = Template('''<form action="">
+        t = Template('''<form>
 {{ form.non_field_errors }}
 {{ form.non_field_errors }}
 {{ form.username.errors.as_ul }}<p><label>Your username: {{ form.username }}</label></p>
 {{ form.username.errors.as_ul }}<p><label>Your username: {{ form.username }}</label></p>
 {{ form.password1.errors.as_ul }}<p><label>Password: {{ form.password1 }}</label></p>
 {{ form.password1.errors.as_ul }}<p><label>Password: {{ form.password1 }}</label></p>
@@ -2657,7 +2657,7 @@ Good luck picking a username that doesn&#39;t already exist.</p>
             t.render(Context({
             t.render(Context({
                 'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
                 'form': UserRegistration({'username': 'django', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
             })),
             })),
-            """<form action="">
+            """<form>
 <ul class="errorlist nonfield"><li>Please make sure your passwords match.</li></ul>
 <ul class="errorlist nonfield"><li>Please make sure your passwords match.</li></ul>
 <p><label>Your username: <input type="text" name="username" value="django" maxlength="10" required></label></p>
 <p><label>Your username: <input type="text" name="username" value="django" maxlength="10" required></label></p>
 <p><label>Password: <input type="password" name="password1" required></label></p>
 <p><label>Password: <input type="password" name="password1" required></label></p>

+ 1 - 1
tests/templates/form_view.html

@@ -2,7 +2,7 @@
 {% block title %}Submit data{% endblock %}
 {% block title %}Submit data{% endblock %}
 {% block content %}
 {% block content %}
 <h1>{{ message }}</h1>
 <h1>{{ message }}</h1>
-<form method="post" action="">
+<form method="post">
 {% if form.errors %}
 {% if form.errors %}
 <p class='warning'>Please correct the errors below:</p>
 <p class='warning'>Please correct the errors below:</p>
 {% endif %}
 {% endif %}

+ 1 - 1
tests/templates/login.html

@@ -5,7 +5,7 @@
 <p>Your username and password didn't match. Please try again.</p>
 <p>Your username and password didn't match. Please try again.</p>
 {% endif %}
 {% endif %}
 
 
-<form method="post" action="">
+<form method="post">
 <table>
 <table>
 <tr><td><label for="id_username">Username:</label></td><td>{{ form.username }}</td></tr>
 <tr><td><label for="id_username">Username:</label></td><td>{{ form.username }}</td></tr>
 <tr><td><label for="id_password">Password:</label></td><td>{{ form.password }}</td></tr>
 <tr><td><label for="id_password">Password:</label></td><td>{{ form.password }}</td></tr>

+ 3 - 3
tests/test_utils/tests.py

@@ -691,15 +691,15 @@ class HTMLEqualTests(SimpleTestCase):
 
 
     def test_contains_html(self):
     def test_contains_html(self):
         response = HttpResponse('''<body>
         response = HttpResponse('''<body>
-        This is a form: <form action="" method="get">
+        This is a form: <form method="get">
             <input type="text" name="Hello" />
             <input type="text" name="Hello" />
         </form></body>''')
         </form></body>''')
 
 
         self.assertNotContains(response, "<input name='Hello' type='text'>")
         self.assertNotContains(response, "<input name='Hello' type='text'>")
-        self.assertContains(response, '<form action="" method="get">')
+        self.assertContains(response, '<form method="get">')
 
 
         self.assertContains(response, "<input name='Hello' type='text'>", html=True)
         self.assertContains(response, "<input name='Hello' type='text'>", html=True)
-        self.assertNotContains(response, '<form action="" method="get">', html=True)
+        self.assertNotContains(response, '<form method="get">', html=True)
 
 
         invalid_response = HttpResponse('''<body <bad>>''')
         invalid_response = HttpResponse('''<body <bad>>''')