I'm using the combined get/post approach in file.app.views.msg() but when you click the 'Delete' button the request object passed to my msg() method returns false when you evaluate request.POST, so the GET view just gets rendered again.
I tried updating the GET template to hardcode the action part of the form with a trailing slash instead of using "." like this:
Short version: <input type='submit' value='Delete' name="delete"> ^^^^^^^^^^^^^
Long version: request.POST is (essentially) a dictionary of post variables. As such, if it is empty, it evaluates to False, even if the request method is 'POST'. In your form, you don't have a single 'successful' field -- the only field is an <input>, and since it doesn't have a 'name' it can't be successful.
On 6/17/06, Luke Plant <L.Plant...@cantab.net> wrote:
> Long version: > request.POST is (essentially) a dictionary of post variables. As such, > if it is empty, it evaluates to False, even if the request method is > 'POST'. In your form, you don't have a single 'successful' field -- > the only field is an <input>, and since it doesn't have a 'name' it > can't be successful.
A post is a post w/ or w/o successful controls. How about putting a dummy into the dictionary to force true?
Yeah, this is kludgy, but the alternative is to put in a attribute on the request object to say "is this a post?" or force people to fix "bugs" in their valid HTML. :)
On Sat, 2006-06-17 at 19:44 -0500, Jeremy Dunck wrote: > On 6/17/06, Luke Plant <L.Plant...@cantab.net> wrote: > > Long version: > > request.POST is (essentially) a dictionary of post variables. As such, > > if it is empty, it evaluates to False, even if the request method is > > 'POST'. In your form, you don't have a single 'successful' field -- > > the only field is an <input>, and since it doesn't have a 'name' it > > can't be successful.
> A post is a post w/ or w/o successful controls. How about putting a > dummy into the dictionary to force true?
> Yeah, this is kludgy, but the alternative is to put in a attribute on > the request object to say "is this a post?" or force people to fix > "bugs" in their valid HTML. :)
There is already a way to test for posts via the request object: request.META['REQUEST_METHOD']. But your suggestion is not unreasonable, so best to file a ticket so that it can be considered without being forgotten.
The implementation side is easy, if we decided to go this route: make sure that __nonzero__() on the MultiValueDict class returns the right thing in these cases.
Jeremy Dunck wrote: > On 6/17/06, Luke Plant <L.Plant...@cantab.net> wrote: >> Long version: >> request.POST is (essentially) a dictionary of post variables. As such, >> if it is empty, it evaluates to False, even if the request method is >> 'POST'. In your form, you don't have a single 'successful' field -- >> the only field is an <input>, and since it doesn't have a 'name' it >> can't be successful.
> A post is a post w/ or w/o successful controls. How about putting a > dummy into the dictionary to force true?
> Yeah, this is kludgy, but the alternative is to put in a attribute on > the request object to say "is this a post?" or force people to fix > "bugs" in their valid HTML. :)
That's what request.META["REQUEST_METHOD"] is for.
-- --Max Battcher-- http://www.worldmaker.net/ "I'm gonna win, trust in me / I have come to save this world / and in the end I'll get the grrrl!" --Machinae Supremacy, Hero (Promo Track)
On 6/17/06, Malcolm Tredinnick <malc...@pointy-stick.com> wrote:
> The implementation side is easy, if we decided to go this route: make > sure that __nonzero__() on the MultiValueDict class returns the right > thing in these cases.
Sorry, I dug around in python introspection docs a bit trying to find what forces in bool() conversion, but came up empty. My response wasn't as useful as it could have been. :)
On 6/17/06, Malcolm Tredinnick <malc...@pointy-stick.com> wrote:
> There is already a way to test for posts via the request object: > request.META['REQUEST_METHOD']. But your suggestion is not unreasonable, > so best to file a ticket so that it can be considered without being > forgotten.
On 6/17/06, Malcolm Tredinnick <malc...@pointy-stick.com> wrote:
> There is already a way to test for posts via the request object: > request.META['REQUEST_METHOD']. But your suggestion is not unreasonable, > so best to file a ticket so that it can be considered without being > forgotten.
I'm not convinced that it'd be a good thing to have request.POST evaluate to True in these cases, but the reasoning is somewhat pedantic.
First and foremost, there's a logical difference between the request method and the request parameters, so it makes sense that a test for the method could evaluate to True while a test for the parameters could evaluate to False.
Second, since request.POST is supposed to be a "dictionary-like" object, this would be unintuitive and, dare I say, "magical" behavior -- an empty dictionary is False.
And, of course, there are practical considerations; if I want a view to return particular output when someone POSTs with no content, now instead of the expected "if not request.POST" -- checking for an empty dictionary -- I have to come up with other tests like looking at the length of request.POST to see if it's "empty but True". Again this is unintuitive.
-- "May the forces of evil become confused on the way to your house." -- George Carlin
On 6/17/06, James Bennett <ubernost...@gmail.com> wrote:
> I'm not convinced that it'd be a good thing to have request.POST > evaluate to True in these cases, but the reasoning is somewhat > pedantic.
I put the comment on the ticket.
The use of request.POST seems overloaded to mean both "is it a post" and "what are the post variables" in the code. But implementation doesn't matter to me.
I'm not in huge angst here, I just hoped to remove a newbie pitfall.
On 6/17/06, James Bennett <ubernost...@gmail.com> wrote:
> I'm not convinced that it'd be a good thing to have request.POST > evaluate to True in these cases, but the reasoning is somewhat > pedantic.
> First and foremost, there's a logical difference between the request > method and the request parameters, so it makes sense that a test for > the method could evaluate to True while a test for the parameters > could evaluate to False.
> Second, since request.POST is supposed to be a "dictionary-like" > object, this would be unintuitive and, dare I say, "magical" behavior > -- an empty dictionary is False.
I agree 100% with James on this one. Having request.POST be an empty dictionary evaluating to True -- that's just too odd. I think we ought to bite the bullet and add request.method, which would be a shortcut to a normalized (all caps?) version of request.META['REQUEST_METHOD'], which is cumbersome to type and might not (?) always be upper case.
Adrian
-- Adrian Holovaty holovaty.com | djangoproject.com
Adrian Holovaty wrote: > I think we ought > to bite the bullet and add request.method, which would be a shortcut > to a normalized (all caps?) version of request.META['REQUEST_METHOD'], > which is cumbersome to type and might not (?) always be upper case.
Per HTTP all request methods are defined in exact case ('GET', 'POST', 'PUT', 'DELETE', ...). No browser will ever send it otherwise even if you have '<form method="post">' in HTML. So in a view method 'Post' is not HTTP's POST and should be treated as garbage.
Luckily Django's pattern of doing:
if request.POST: #post else: #get
is safe since every unknown method will end up in 'GET' part which supposed to be idempotent anyway. And for better safety a user can list exact methods with @require_http_methods decorator (which is somewhat broken currently, I keep forgetting to file a ticket, will do now).
Adrian Holovaty wrote: > On 6/17/06, James Bennett <ubernost...@gmail.com> wrote: >> I'm not convinced that it'd be a good thing to have request.POST >> evaluate to True in these cases, but the reasoning is somewhat >> pedantic.
>> First and foremost, there's a logical difference between the request >> method and the request parameters, so it makes sense that a test for >> the method could evaluate to True while a test for the parameters >> could evaluate to False.
>> Second, since request.POST is supposed to be a "dictionary-like" >> object, this would be unintuitive and, dare I say, "magical" behavior >> -- an empty dictionary is False.
> I agree 100% with James on this one. Having request.POST be an empty > dictionary evaluating to True -- that's just too odd. I think we ought > to bite the bullet and add request.method, which would be a shortcut > to a normalized (all caps?) version of request.META['REQUEST_METHOD'], > which is cumbersome to type and might not (?) always be upper case.
i think the problem here is that we're mixing two things:
1. the method 2. the sent data
for GET requests it's simple, because the sent data is in the querystring, so for GET requests the GET dictionary will contain the relevant data.
but a POST request is more complicated. here you can do something like:
POST <MultiValueDict: {'second': ['2nd'], 'submit': ['Submit'], 'first': ['1st']}>
GET <MultiValueDict: {'query': ['string']}>
and i think that people usually want do differentiate between GET and POST requests, not GET and POST data.
so i'm also for request.method. maybe even is_get() and is_post(). i understand that even currently you can do it with request.META['REQUEST_METHOD'], but it's too long and ugly. and because of that it does not look like the recommended approach.
> Long version: > request.POST is (essentially) a dictionary of post variables. As such, > if it is empty, it evaluates to False, even if the request method is > 'POST'.
Bill de hÓra wrote: > Luke Plant wrote: >> Long version: >> request.POST is (essentially) a dictionary of post variables. As such, >> if it is empty, it evaluates to False, even if the request method is >> 'POST'.
> That's a bug, imo.
Never mind - request.META["REQUEST_METHOD"] is news to me. On reflection, the idiom request.POST is broken; time to fix my code.
I have to agree that it should return false if there is no data. Otherwise how are you going to tell the difference between a POST with no data and a POST with data.
Another alternative is maybe request.method.POST and request.method.GET for testing the method.
>> Long version: >> request.POST is (essentially) a dictionary of post variables. As >> such, >> if it is empty, it evaluates to False, even if the request method is >> 'POST'.
On 6/17/06, Adrian Holovaty <holov...@gmail.com> wrote:
> I agree 100% with James on this one. Having request.POST be an empty > dictionary evaluating to True -- that's just too odd. I think we ought > to bite the bullet and add request.method, which would be a shortcut > to a normalized (all caps?) version of request.META['REQUEST_METHOD'], > which is cumbersome to type and might not (?) always be upper case.
As of changeset [3164], I've added the attribute request.method, which is a string such as "POST" or "GET".
I debated making request.method a magic object that would let you check via attribute access, as some syntactic sugar:
if request.method.POST:
...but I decided that would be too magic, and it would actually get in the way of people doing stuff like "if request.method in ('GET', 'POST')". A plain string will do.
Adrian
-- Adrian Holovaty holovaty.com | djangoproject.com