Can you set default values for request.get() (not post.get)? - django

I have 2 HTML submission fields under one submit button, one of which is optional. I'm using the 'get' method to retrieve submitted data, but I want the optional field to have a default value just in case the user submits an empty form. If I don't do this, I get a MultiValueDictKeyError.
if request.method == 'GET':
# required
name = request.GET['name']
# optional
color = request.GET['color']
I think a possible solution is try / except for every field, but is there a more elegant method? I know for get.post() you can do something like
color = request.POST.get('color', False)
But this doesn't seem to work for just request.get()
Any ideas?
Thanks,
fertileneutrino

Confused here... request.get() won't work, but request.GET.get() should. Did you just mistype or were you actually using request.get()?

Related

Django - Create new object in Form, update select box and save it

I think what I'm trying to achieve is not hard, but I have no clue how to do it hehehehe !
Basically what I need is the feature that we have in Django Admin, when you are creating a new object, if you have a Foreign Key, you can add new data (opening a pop-up), save it and then the select box updates automatically.
What I have is this form:
I know that would be easy to do it with some Javascript, but my point is, Django has some rules, and as far I know, I can't add new data to a form already created, right? Otherwise Django won't validate this form. How could I achieve this?
PS: "Local" is the select box where I want to add new data. The user should be able to create a new Local on this page, instead of going to another page to do it. Thanks :)
Here your question:
I can't add new data to a form already created, right? Otherwise Django won't validate this form. How could I achieve this?
Then the answer:
you are right, django will check values match form value rules. But:
realize that your main form is invoked for twice: on GET and on POST. Between both form executions you make changes on database values trhough your new form. That means that in second main form invocation the value added to database is available:
field1 = forms.ModelChoiceField(queryset= ***1*** )
***1***: on second invocation new value is already available on field1.
Then, you don't should to be afraid about this subject, the new value will be available on form on your main form POST request.
Nothing wrong with updating the value using javascript as long the key in your new combo box has the right key in the database then it should be ok.
Call this function after you saved the last entry.
function refreshLocal(){
$.get(window.location.href, '', function(html){
// change the id to the local combox's id
var serverLocalDropBox = $(html).find('#id_local');
if (serverLocalDropBox.length){
$('#id_local').replaceWith(serverLocalDropBox);
}
})
}
If you don't want to use javascript solution, you can post the form with refresh flag and on the server side if you see that flag just don't validate and return the form as is. Since you have a new entry in the foreignkey it will automatically update the queryset to include the new entry.
function serverRefreshLocal(){
var $form = $('#your_form_id');
$form.append('<input type="hidden" name="refresh" value="true" />');
// you can use ajax submit and ajax refresh here if you don't want to leave the page
$form.submit();
}
// Server Side
def your_form_post_view(request):
if request.POST.get('refresh', 'false') == 'true':
# initial is the trick to save user input
your_form = YourForm(initial=request.POST)
context = {
'form': your_form,
}
return render(request, 'your_template.html', context)
# your view code goes here

Django 1.6 request POST/GET empty

I use a function-based view and try to validate a form which is submitted over Ajax (with jquery.form plugin):
Content-Type:application/json; charset=UTF-8
X-CSRFToken:jRr4oOBHQS5mtwopN69xHocjWJBYuJHa
X-Requested-With:XMLHttpRequest
Request payload:
csrfmiddlewaretoken=jRr4oOBHQS5mtwopN69xHocjWJBYuJHa&code=123456
now, in the view function, I have request.GET/POST empty, but request.body as a string, and I can't validate the form.
form = CodeCheckForm(parse_qs(request.body))
form.is_valid()
In the second line, the clean* functions aren't called, which is really weird.
Changing to use data or initial doesn't help either:
form = CodeCheckForm(data=parse_qs(request.body))
What am I doing wrong?
EDIT: among the answers, the decisive was to change the content type. In jquery.forms plugin I set contentType option to application/x-www-form-urlencoded; charset=UTF-8.
EDIT 2: there are 2 ways to supply arbitrary data around the standard way, but they weren't suitable in my case:
1) form = MyForm(parse_qs(request.body)) is almost correct, but Django forms expect this to be a QueryDict, and have some properties, while this is a usual dict. Form class raises exception and crashes the view.
2) form = MyForm(data=parse_qs(request.body)) works, but does not call clean* functions. This is intentional, as Django developers made this way as a way around clean functions. You're supposed to validate the data yourself, and then submit it this way. Django form then does not clean it in any way and decides the form is not validated, hence form.is_valid() will be False.
The GET and POST only contain form data. They are empty for you because your content type is 'application/json'. It's not clear to me why you've used this content type, since the payload looks like form encoded data to me, not json.
If you manually parse the payload, use the data argument. The initial argument is only used to show initial values. If you don't bind the form to data, then the form is unbound, and will never be valid.
I'm not sure why the following line didn't work. What is the value of parse_qs(request.body)?
form = CodeCheckForm(parse_qs(request.body))

Changing field values in form.clean_xxx

I want to validate form input and if required modify a field used to build a subdomain for a URL. IE take out the illegal characters. Here is a VERY simple example to illustrate the problem.
class MyForm(forms.Form):
def clean_f(self):
f = self.cleaned_data['f']
if f.count('%'):
f = f.replace('%', '')
return f
This doesn't change the form. I want the user to see the 'stripped' value, but it always shows the submitted value.
Is it possible to do this with a simple form clean_xxx method?
Otherwise I will use my AJAX form processor.
Thanks

DJANGO - change a form value with request.POST?

so i have this code:
post = request.POST.copy()
post['relationshipId'] = theRelationship.id
theStory = StoryForm(post, request = request, initial {'relationshipId' : theRelationship.id})
initially, my code looked like this:
theStory = StoryForm(request.POST, request = request, initial {'relationshipId' : theRelationship.id})
which caused validation problems. The validator would complain that the relationshipId wasn't set. Why would this be?
EDIT: the first block of code works fine, and I am super-happy with it. The question pertains to the second block of code, which was initially what I had (and what i've just spend some time working on) which, to me, is acting "weird"
The first snippet sets the relationshipId field dynamically, instead of taking it from the POST parameters supplied in the web request.
The second snippet will take that value directly from request.POST, so if your form submits an invalid value, or if no value is given, it will not validate.
The initial argument only applies to unbound forms (see https://docs.djangoproject.com/en/1.5/ref/forms/fields/#initial). You could leave it out here, because you are binding the form to post or request.POST.

In a Django form clean function, how can one reliably test if an optional field was filled out?

In Django, I have a form class with a clean function. In this clean function, I check to see if an optional select box was filled out.
def clean_session_1(self):
# Check if session_1 is filled out.
if self.cleaned_data['session_1']:
# more validation
return self.cleaned_data['session_1']
If the select box was filled out, then more validation of the field ensues.
For some reason, this code is not testing whether the field was filled out and runs "more validation" every time.
I was wondering how can one reliably test if this field "session_1" was filled out? Thanks!
Access self._raw_value('key') to get the raw entry in the form field (i.e. just text, not processed to a python object).
Update: As Ahsan says, do it in the clean method. You should probably call the superclass clean method also.
You can check it in form's clean method
def clean(self):
data = self.data # data contains all fields, optional or required both
optional_field = data.get('optional_field', None)
# more validation
return optional_field