Form object not iterable in Django - python

I want to assign the input of a form to a function in my view but I keep getting this error. Please help do I fix it.
Error
receiver = list(ToolsForm.declared_fields['receiver_mail'])
TypeError: 'CharField' object is not iterable

You can obtain the value associated with the receiver_mail field with:
receiver = form.cleaned_data['receiver_mail']
so without using list(…) part and with .cleaned_data [Django-doc], the form should be an instance of ToolForm, not a reference to the ToolForm class. Before you can retrieve the data, you will first need to validate the form, so:
form = ToolsForm(request.POST, request.FILES)
if form.is_valid():
receiver = form.cleaned_data['receiver_mail']

Related

Get saved object of a model form in Django?

I just want to access model details just after posting it with model form in Django. This guy also had asked the same thing but when i try the
accepted answer, it returns none type value.
Here is my code in 'views.py':
if request.method == 'POST':
if request.user.is_authenticated():
form = PostStoryForm(request.POST)
if form.is_valid():
obj = form.save(commit=False)
obj.author = request.user
new_post = obj.save()
print(new_post)
The Code above saves the form to the database successfully but 'new_post' variable is 'None'. For example when i tried to access 'new_post.title' which is a field in my model, it returns 'AttributeError' which says 'NoneType' object has no attribute 'title'
what am i doing wrong?
The models save() method does not return the instance
obj.author = request.user
obj.save() # this does not return anything. It just saves the instance it is called on.
Your instance already has the author set.
To access auto populated fields that haven't been set yet, you will have to fetch it from the database again after saving. This is the case, when the instance you called save() on did not already exist before.
new_obj = MyModel.objects.get(id=obj.id)

Django form returns is_valid() = False and no errors

I have simple view in django app, which I want to show only when one of the forms is valid. I have something like:
#login_required
#require_role('admin')
def new_package(request):
invoicing_data_form = InvoicingDataForm(instance=request.user.account.company.invoicingdata)
if invoicing_data_form.is_valid():
# all here
return HttpResponse('Form valid')
else:
logger.info("Form invalid")
return HttpResponse(json.dumps(invoicing_data_form.errors)
I always get log info message that form is invalid, however, I get nothing in
invoicing_data_form.errors
It is very strange, because I am validating this form in other view using user input data and it works just fine. Any idea?
EDIT:
Just for clarification.
I am not requesting any data from user in this form.
I am using this form to validate some model instance (this form is subclassing from ModelForm).
That's because you're not "feeding" your form.
Do this:
invoicing_data_form = InvoicingDataForm(instance=invoice, data=request.POST or None)
You have an unbound form.
https://docs.djangoproject.com/en/1.7/ref/forms/api/#bound-and-unbound-forms
A Form instance is either bound to a set of data, or unbound.
If it’s bound to a set of data, it’s capable of validating that data and rendering the form as HTML with the data displayed in the HTML.
If it’s unbound, it cannot do validation (because there’s no data to validate!), but it can still render the blank form as HTML.
To bind data to a form, pass the data as a dictionary as the first parameter to your Form class constructor:
invoicing_data_form = InvoicingDataForm(request.POST or None, instance=invoice)
If you're already giving request.POST to your form using request.POST or None, but it's still invalid without errors, check that there isn't any redirect going on. A redirect loses your POST data and your form will be invalid with no errors because it's unbound.
I got this for AuthenticationForm which needs AuthenticationForm(None, request.POST) see Using AuthenticationForm in Django
I want to expand on the answer by #yuji-tomita-tomita
I typically use a CBV approach in Django, and how I'm handling forms:
def post(self, request, *args, **kwargs):
form = self.get_form()
if form.is_valid():
# do things
Reading the source code I noticed that self.get_form() using get_form_kwargs(self) to populate the form with request.POST, thus getting bound to data. So if you're overloading it like I did:
def get_form_kwargs(self):
company = self.get_company()
return {"company": company}
Make sure to call the super(), and it will finally work:
def get_form_kwargs(self):
company = self.get_company()
kwargs = super().get_form_kwargs()
kwargs.update({"company": company})
return kwargs

django forms, cleaned_data is empty

I have been playing around with forms a little and cant seem to understand why cleaned_data is not giving me any usable output (aka the dict appears to be completely empty). What id like to do is have a form on a page with two date selector so the user can select a from and to date that Django will then query a database that has periodic thermocouple measurements and create a table.
views.py
def temperature_data(request):
date_select_form = CalLabDateSelect(request.POST)
if request.method == 'POST':
if date_select_form.is_valid(): # All validation rules pass
print "this should be some date/time data from date_select_form:", date_select_form.cleaned_data
#return HttpResponseRedirect('/test_page/') # Redirect after POST
raw_data = Callab.objects.all().using('devices').order_by('-time')
return render_to_response("temperature_display.html",
locals(),
context_instance=RequestContext(request))
forms.py
def make_custom_datefield(f):
formfield = f.formfield()
if isinstance(f, models.DateField):
formfield.widget.format = '%m/%d/%Y'
formfield.widget.attrs.update({'class':'datePicker', 'readonly':'true'})
return formfield
class CalLabDateSelect(forms.Form):
formfield_callback = make_custom_datefield
when i visit the page and select a date then submit the form i see this outputted to the console:
QueryDict: {u'date': [u'10/04/2014'], u'csrfmiddlewaretoken': [u'C5PPlMU3asdFwyma9azFDs4DN33CMmvK']}
this should be some date/time data from date_select_form: {}
all i notice is that the dictionary is empty {} but the request.POST data shows 10/04/2014???
any ideas why this is happening??
And thank you all very much for any help in understand this!!
Your form doesn't actually define any fields, so I don't know what you're expecting to get in cleaned_data. formfield_callback is only useful in a ModelForm, where it operates on the fields already defined by a model: but your form is not based on a model.
Either use a model form, or define your form fields explicitly in your form class.

'WSGIRequest' object is not subscriptable

I'm getting this error in this function in my views.py file. It's confusing because I don't know what 'WSGIRequest' is or why it's giving me problems. I know I have a variable called "newUser" because when I take out that one line the print(request.POST) line prints it out.
def AddNewUser(request):
a=AMI()
if(request.method == "POST"):
print(request.POST)
print(request["newUser"])
csrfContext = RequestContext(request)
return render_to_response("ac/AddNewUser.html", csrfContext)
`
Why am I getting this error?
It means that WSGIRequest does not implement __getitem__. You are trying to treat the HttpRequest object like a dictionary but it's not. If you want to access this newUser variable use the POST object, which implements a dictionary-like interface:
request.POST['newUser']
You'd do well to peruse the Django docs in situations like this.

django ModelForm save() method issue

I have a model form:
class SnippetForm(ModelForm):
class Meta:
model = Snippet
exclude = ['author', 'slug']
and I want to be able to edit a particular instance by using this:
def edit_snippet(request, snippet_id):
#look up for that snippet
snippet = get_object_or_404(Snippet, pk=snippet_id)
if request.user.id != snippet.author.id:
return HttpResponseForbidden()
if request.method == 'POST':
form = SnippetForm(data=request.POST, instance=snippet)
if form.is_valid():
form.save()
return HttpResponseRedirect(snippet.get_absolute_url())
else:
form = SnippetForm(instance=snippet)
return render_to_response(SNIPPET_EDIT_TEMPLATE,
{'form':form, 'add':False, 'user':request.user},
RequestContext(request))
Notice that at the line
form = SnippetForm(data=request.POST, instance=snippet)
, I created a form that use the data supplied from the user, and bound it with the instance found using the primary key (received from the url). According to django documentation, when I call save() the existing instance should be updated with POSTED data. Instead, what I see is a new object is created and saved into the database. What went wrong? Thanks a lot.
[Edit] This is really embarrassed. The code indeed has nothing wrong with it. The only thing that messed up the whole thing was the action I put in the template (as I use a same template for add and edit a snippet)....Thanks a lot for your help, really appreciate that.
I don't see why it would happen. What version of django is it?
In any case, you can manually force update passing the corresponding argument.
form = SnippetForm(data=request.POST, instance=snippet, force_update=True)

Categories