views:

66

answers:

3

I would like to run a check on the IP-adress when users post with django comments.

I can easily override and customize the form used by django.comments, but I need access to the request object to add an IP-test to its clean(). Is it possible to get access to this in a clean way?

An alternative could be to check the IP when recieving the save signal, but then the only way to abort the save seems to be returning a code 400 to the user.

A: 

One possible way, but you still do not have request object in this level of validation...

class SomeForm(forms.ModelForm):
    somefield = forms.CharField(...)

    def check_somefield(self):
        somefield = self.cleaned_data['somefield']
        ...  #do what you want
    return somefield

Hope this can help, or i do not understand what you want correctly.

FallenAngel
A: 

I think this is the answer to your question:

http://stackoverflow.com/questions/1057252/django-how-do-i-access-the-request-object-or-any-other-variable-in-a-forms-clea

anand
The top answer in that thread is to pass the request object to the form. In django.contrib.comments you call the form with a template tag, and you can't pass it additional variables as far as I can see.
Hobhouse
+1  A: 

The comments framework provides a comment_will_be_posted signal: http://docs.djangoproject.com/en/1.2/ref/contrib/comments/signals/#comment-will-be-posted

If you register at this signal, your handler will be passed the (not yet saved) comment object and the request as arguments. If your handler returns False, the post_comment view answers with CommentPostBadRequest, as it does on any other sort of error like failed form validation.

Bernd Petersohn
This will work, but I would like to return the form with an informative message to the user instead of throwing the CommentPostBadRequest which will return a 400 error.
Hobhouse
@Hobhouse: Then the only solution I see is to provide your own version of `post_comment`. The implementation in `django/contrib/comments/views/comments.py` does not seem to provide any further hooks for your purpose. However, if you check the IP address for security reasons, it is probably safer to just answer with a 400 status.
Bernd Petersohn
@Hobhouse: OK, a further solution could be to provide a middleware class that implements a `process_request` method which stores the current request in a thread-local variable. This way you could access the current request from your form. See http://docs.djangoproject.com/en/1.2/topics/http/middleware/#writing-your-own-middleware and http://docs.python.org/library/threading.html#threading.local
Bernd Petersohn