diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0d20b64
      
    
    
      
      diff --git a/django/contrib/comments/views/moderation.py b/django/contrib/comments/views/moderation.py
index 3334b09..13e08ff 100644
      
        
          
        
        
          
            | a | b | def flag(request, comment_id, next=None): | 
        
        
          
            | 34 | 34 | created = created, | 
          
            | 35 | 35 | request = request, | 
          
            | 36 | 36 | ) | 
        
        
          
            | 37 |  | return next_redirect(request.POST.copy(), next, flag_done, c=comment.pk) | 
          
            |  | 37 | if request.POST.has_key('next'): | 
          
            |  | 38 | next = request.POST.get('next') | 
          
            |  | 39 | elif request.GET.has_key('next'): | 
          
            |  | 40 | next = request.GET.get('next') | 
          
            |  | 41 | return next_redirect(request.POST.copy(),next, flag_done, c=comment.pk) | 
        
        
          
            | 38 | 42 |  | 
          
            | 39 | 43 | # Render a form on GET | 
          
            | 40 | 44 | else: | 
        
        
          
            |  | 45 | next = request.GET.get('next',next) | 
        
        
          
            | 41 | 46 | return render_to_response('comments/flag.html', | 
          
            | 42 | 47 | {'comment': comment, "next": next}, | 
          
            | 43 | 48 | template.RequestContext(request) | 
        
        
          
            | … | … | def delete(request, comment_id, next=None): | 
        
        
          
            | 74 | 79 | created = created, | 
          
            | 75 | 80 | request = request, | 
          
            | 76 | 81 | ) | 
        
        
          
            |  | 82 | if request.POST.has_key('next'): | 
          
            |  | 83 | next = request.POST.get('next') | 
          
            |  | 84 | elif request.GET.has_key('next'): | 
          
            |  | 85 | next = request.GET.get('next') | 
        
        
          
            | 77 | 86 | return next_redirect(request.POST.copy(), next, delete_done, c=comment.pk) | 
          
            | 78 | 87 |  | 
          
            | 79 | 88 | # Render a form on GET | 
          
            | 80 | 89 | else: | 
        
        
          
            |  | 90 | next = request.GET.get('next',next) | 
        
        
          
            | 81 | 91 | return render_to_response('comments/delete.html', | 
          
            | 82 | 92 | {'comment': comment, "next": next}, | 
          
            | 83 | 93 | template.RequestContext(request) | 
        
        
          
            | … | … | def approve(request, comment_id, next=None): | 
        
        
          
            | 117 | 127 | created = created, | 
          
            | 118 | 128 | request = request, | 
          
            | 119 | 129 | ) | 
        
        
          
            |  | 130 | if request.POST.has_key('next'): | 
          
            |  | 131 | next = request.POST.get('next') | 
          
            |  | 132 | elif request.GET.has_key('next'): | 
          
            |  | 133 | next = request.GET.get('next') | 
        
        
          
            | 120 | 134 | return next_redirect(request.POST.copy(), next, approve_done, c=comment.pk) | 
          
            | 121 | 135 |  | 
          
            | 122 | 136 | # Render a form on GET | 
          
            | 123 | 137 | else: | 
        
        
          
            |  | 138 | next = request.GET.get('next',next) | 
        
        
          
            | 124 | 139 | return render_to_response('comments/approve.html', | 
          
            | 125 | 140 | {'comment': comment, "next": next}, | 
          
            | 126 | 141 | template.RequestContext(request) | 
        
      
    
    
      
      diff --git a/docs/ref/contrib/comments/index.txt b/docs/ref/contrib/comments/index.txt
index f6e1553..4bfedcd 100644
      
        
          
        
        
          
            | a | b | Quick start guide | 
        
        
          
            | 24 | 24 |  | 
          
            | 25 | 25 | To get started using the ``comments`` app, follow these steps: | 
          
            | 26 | 26 |  | 
        
        
          
            | 27 |  | #. Install the comments framework by adding ``'django.contrib.comments'`` to      | 
          
            |  | 27 | #. Install the comments framework by adding ``'django.contrib.comments'`` to | 
        
        
          
            | 28 | 28 | :setting:`INSTALLED_APPS`. | 
          
            | 29 | 29 |  | 
          
            | 30 | 30 | #. Run ``manage.py syncdb`` so that Django will create the comment tables. | 
          
            | 31 | 31 |  | 
          
            | 32 | 32 | #. Add the comment app's URLs to your project's ``urls.py``: | 
        
        
          
            | 33 |  |  | 
          
            |  | 33 |  | 
        
        
          
            | 34 | 34 | .. code-block:: python | 
          
            | 35 | 35 |  | 
          
            | 36 | 36 | urlpatterns = patterns('', | 
        
        
          
            | … | … | To get started using the ``comments`` app, follow these steps: | 
        
        
          
            | 41 | 41 |  | 
          
            | 42 | 42 | #. Use the `comment template tags`_ below to embed comments in your | 
          
            | 43 | 43 | templates. | 
        
        
          
            | 44 |  |  | 
          
            |  | 44 |  | 
        
        
          
            | 45 | 45 | You might also want to examine :ref:`ref-contrib-comments-settings`. | 
        
        
          
            | 46 |  |  | 
          
            |  | 46 |  | 
        
        
          
            | 47 | 47 | Comment template tags | 
          
            | 48 | 48 | ===================== | 
          
            | 49 | 49 |  | 
        
        
          
            | … | … | different ways you can specify which object to attach to: | 
        
        
          
            | 67 | 67 | #. Refer to the object directly -- the more common method. Most of the | 
          
            | 68 | 68 | time, you'll have some object in the template's context you want | 
          
            | 69 | 69 | to attach the comment to; you can simply use that object. | 
        
        
          
            | 70 |  |  | 
          
            | 71 |  | For example, in a blog entry page that has a variable named ``entry``,   | 
          
            |  | 70 |  | 
          
            |  | 71 | For example, in a blog entry page that has a variable named ``entry``, | 
        
        
          
            | 72 | 72 | you could use the following to load the number of comments:: | 
        
        
          
            | 73 |  |  | 
          
            |  | 73 |  | 
        
        
          
            | 74 | 74 | {% get_comment_count for entry as comment_count %}. | 
        
        
          
            | 75 |  |  | 
          
            |  | 75 |  | 
        
        
          
            | 76 | 76 | #. Refer to the object by content-type and object id. You'd use this method | 
          
            | 77 | 77 | if you, for some reason, don't actually have direct access to the object. | 
        
        
          
            | 78 |  |  | 
          
            |  | 78 |  | 
        
        
          
            | 79 | 79 | Following the above example, if you knew the object ID was ``14`` but | 
          
            | 80 | 80 | didn't have access to the actual object, you could do something like:: | 
        
        
          
            | 81 |  |  | 
          
            |  | 81 |  | 
        
        
          
            | 82 | 82 | {% get_comment_count for blog.entry 14 as comment_count %} | 
        
        
          
            | 83 |  |  | 
          
            |  | 83 |  | 
        
        
          
            | 84 | 84 | In the above, ``blog.entry`` is the app label and (lower-cased) model | 
          
            | 85 | 85 | name of the model class. | 
          
            | 86 | 86 |  | 
        
        
          
            | … | … | For example:: | 
        
        
          
            | 99 | 99 | {% for comment in comment_list %} | 
          
            | 100 | 100 | ... | 
          
            | 101 | 101 | {% endfor %} | 
        
        
          
            | 102 |  |  | 
          
            |  | 102 |  | 
        
        
          
            | 103 | 103 | This returns a list of :class:`~django.contrib.comments.models.Comment` objects; | 
          
            | 104 | 104 | see :ref:`the comment model documentation <ref-contrib-comments-models>` for | 
          
            | 105 | 105 | details. | 
        
        
          
            | … | … | To count comments attached to an object, use :ttag:`get_comment_count`:: | 
        
        
          
            | 116 | 116 | For example:: | 
          
            | 117 | 117 |  | 
          
            | 118 | 118 | {% get_comment_count for event as comment_count %} | 
        
        
          
            | 119 |  |  | 
          
            |  | 119 |  | 
        
        
          
            | 120 | 120 | <p>This event has {{ comment_count }} comments.</p> | 
        
        
          
            | 121 |  |  | 
          
            |  | 121 |  | 
        
        
          
            | 122 | 122 |  | 
          
            | 123 | 123 | Displaying the comment post form | 
          
            | 124 | 124 | -------------------------------- | 
        
        
          
            | … | … | If you want more control over the look and feel of the comment form, you use use | 
        
        
          
            | 153 | 153 | you can use in the template:: | 
          
            | 154 | 154 |  | 
          
            | 155 | 155 | {% get_comment_form for [object] as [varname] %} | 
        
        
          
            | 156 |  |  | 
          
            |  | 156 |  | 
        
        
          
            | 157 | 157 | A complete form might look like:: | 
          
            | 158 | 158 |  | 
          
            | 159 | 159 | {% get_comment_form for event as form %} | 
        
        
          
            | … | … | A complete form might look like:: | 
        
        
          
            | 164 | 164 | <td><input type="submit" name="preview" class="submit-post" value="Preview"></td> | 
          
            | 165 | 165 | </tr> | 
          
            | 166 | 166 | </form> | 
        
        
          
            | 167 |  |  | 
          
            |  | 167 |  | 
        
        
          
            | 168 | 168 | Be sure to read the `notes on the comment form`_, below, for some special | 
          
            | 169 | 169 | considerations you'll need to make if you're using this approach. | 
          
            | 170 | 170 |  | 
        
        
          
            | … | … | Redirecting after the comment post | 
        
        
          
            | 185 | 185 |  | 
          
            | 186 | 186 | To specify the URL you want to redirect to after the comment has been posted, | 
          
            | 187 | 187 | you can include a hidden form input called ``next`` in your comment form. For example:: | 
        
        
          
            | 188 |  |  | 
          
            |  | 188 |  | 
        
        
          
            | 189 | 189 | <input type="hidden" name="next" value="{% url my_comment_was_posted %}" /> | 
          
            | 190 | 190 |  | 
        
        
          
            |  | 191 | The ``next`` parameter can be passed into the comment system in a variety of ways, | 
          
            |  | 192 | but POST will always be preferred over GET and the named parameter is always overridden. | 
          
            |  | 193 |  | 
          
            |  | 194 | A ``next`` parameter can be specified in ``urls.py`` with the following line:: | 
          
            |  | 195 |  | 
          
            |  | 196 | (r'^flag/(\d+)/$', flag, {'next': '/I/am/done/'}) | 
          
            |  | 197 |  | 
        
        
          
            | 191 | 198 | .. _notes-on-the-comment-form: | 
          
            | 192 | 199 |  | 
          
            | 193 | 200 | Notes on the comment form | 
        
        
          
            | … | … | should know about: | 
        
        
          
            | 198 | 205 |  | 
          
            | 199 | 206 | * It contains a number of hidden fields that contain timestamps, information | 
          
            | 200 | 207 | about the object the comment should be attached to, and a "security hash" | 
        
        
          
            | 201 |  | used to validate this information. If someone tampers with this data --   | 
          
            |  | 208 | used to validate this information. If someone tampers with this data -- | 
        
        
          
            | 202 | 209 | something comment spammers will try -- the comment submission will fail. | 
        
        
          
            | 203 |  |  | 
          
            |  | 210 |  | 
        
        
          
            | 204 | 211 | If you're rendering a custom comment form, you'll need to make sure to | 
          
            | 205 | 212 | pass these values through unchanged. | 
        
        
          
            | 206 |  |  | 
          
            |  | 213 |  | 
        
        
          
            | 207 | 214 | * The timestamp is used to ensure that "reply attacks" can't continue very | 
          
            | 208 | 215 | long. Users who wait too long between requesting the form and posting a | 
          
            | 209 | 216 | comment will have their submissions refused. | 
        
        
          
            | 210 |  |  | 
          
            |  | 217 |  | 
        
        
          
            | 211 | 218 | * The comment form includes a "honeypot_" field. It's a trap: if any data is | 
          
            | 212 | 219 | entered in that field, the comment will be considered spam (spammers often | 
          
            | 213 | 220 | automatically fill in all fields in an attempt to make valid submissions). | 
        
        
          
            | 214 |  |  | 
          
            |  | 221 |  | 
        
        
          
            | 215 | 222 | The default form hides this field with a piece of CSS and further labels | 
          
            | 216 | 223 | it with a warning field; if you use the comment form with a custom | 
          
            | 217 | 224 | template you should be sure to do the same. | 
        
        
          
            | 218 |  |  | 
          
            |  | 225 |  | 
        
        
          
            | 219 | 226 | .. _honeypot: http://en.wikipedia.org/wiki/Honeypot_(computing) | 
          
            | 220 | 227 |  | 
          
            | 221 | 228 | More information | 
        
      
    
    
      
      diff --git a/tests/regressiontests/comment_tests/tests/moderation_view_tests.py b/tests/regressiontests/comment_tests/tests/moderation_view_tests.py
index b9eadd7..c79c006 100644
      
        
          
        
        
          
            | a | b | from django.contrib.auth.models import User, Permission | 
        
        
          
            | 3 | 3 | from django.contrib.contenttypes.models import ContentType | 
          
            | 4 | 4 | from regressiontests.comment_tests.tests import CommentTestCase | 
          
            | 5 | 5 | from django.contrib.comments import signals | 
        
        
          
            | 6 |  |  | 
          
            |  | 6 | from django.contrib.comments.views.moderation import delete | 
          
            |  | 7 | import re | 
        
        
          
            | 7 | 8 | class FlagViewTests(CommentTestCase): | 
          
            | 8 | 9 |  | 
          
            | 9 | 10 | def testFlagGet(self): | 
        
        
          
            | … | … | class DeleteViewTests(CommentTestCase): | 
        
        
          
            | 92 | 93 | self.client.login(username="normaluser", password="normaluser") | 
          
            | 93 | 94 | response = self.client.post("/delete/%d/" % pk) | 
          
            | 94 | 95 | self.assertEqual(response["Location"], "http://testserver/deleted/?c=%d" % pk) | 
        
        
          
            |  | 96 |  | 
          
            |  | 97 | response = self.client.post("/delete/%d/" % pk,{"next":"/somewhere/else/"}) | 
          
            |  | 98 | location = response["Location"] | 
          
            |  | 99 | match = re.search(r"^http://testserver/somewhere/else/\?c=\d+$", location) | 
          
            |  | 100 | self.failUnless(match != None, "Unexpected redirect location: %s" % location) | 
        
        
          
            | 95 | 101 | c = Comment.objects.get(pk=pk) | 
          
            | 96 | 102 | self.failUnless(c.is_removed) | 
          
            | 97 | 103 | self.assertEqual(c.flags.filter(flag=CommentFlag.MODERATOR_DELETION, user__username="normaluser").count(), 1) | 
        
        
          
            | … | … | class DeleteViewTests(CommentTestCase): | 
        
        
          
            | 106 | 112 |  | 
          
            | 107 | 113 | # Post a comment and check the signals | 
          
            | 108 | 114 | self.testDeletePost() | 
        
        
          
            | 109 |  | self.assertEqual(received_signals, [signals.comment_was_flagged ]) | 
          
            |  | 115 | self.assertEqual(received_signals, [signals.comment_was_flagged,signals.comment_was_flagged]) | 
        
        
          
            | 110 | 116 |  | 
          
            | 111 | 117 | def testDeletedView(self): | 
          
            | 112 | 118 | comments = self.createSomeComments() | 
          
            | 113 | 119 | pk = comments[0].pk | 
          
            | 114 | 120 | response = self.client.get("/deleted/", data={"c":pk}) | 
          
            | 115 | 121 | self.assertTemplateUsed(response, "comments/deleted.html") | 
        
        
          
            |  | 122 |  | 
          
            |  | 123 | def testDeletedViewNextGet(self): | 
          
            |  | 124 | comments = self.createSomeComments() | 
          
            |  | 125 | pk = comments[0].pk | 
          
            |  | 126 | makeModerator("normaluser") | 
          
            |  | 127 | self.client.login(username="normaluser", password="normaluser") | 
          
            |  | 128 | response = self.client.get("/delete/%d/" % pk, data={"next":"/somewhere/else"}) | 
          
            |  | 129 | self.assertEqual(response.context[1]['next'],"/somewhere/else") | 
          
            |  | 130 | self.assertTemplateUsed(response, "comments/delete.html") | 
          
            |  | 131 |  | 
        
        
          
            | 116 | 132 |  | 
          
            | 117 | 133 | class ApproveViewTests(CommentTestCase): | 
          
            | 118 | 134 |  | 
        
      
    
    
      
      diff --git a/tests/regressiontests/comment_tests/urls.py b/tests/regressiontests/comment_tests/urls.py
index 0058689..c183102 100644
      
        
          
        
        
          
            | a | b | urlpatterns = patterns('regressiontests.comment_tests.custom_comments.views', | 
        
        
          
            | 5 | 5 | url(r'^flag/(\d+)/$',    'custom_flag_comment'), | 
          
            | 6 | 6 | url(r'^delete/(\d+)/$',  'custom_delete_comment'), | 
          
            | 7 | 7 | url(r'^approve/(\d+)/$', 'custom_approve_comment'), | 
        
        
          
            |  | 8 |  | 
        
        
          
            | 8 | 9 | ) | 
        
        
          
            | 9 |  |  |