Django form has no attribute 'cleaned_data' - python

This is the code I have, and when I run it on Django, I am met with this error: 'Title' object has no attribute cleaned_data
def new(request):
form = Title(request.POST)
if request.method == "POST":
if form.is_valid:
title = form.cleaned_data["title"]
text = form.cleaned_data["text"]
util.save_entry(title, text)
else:
return render(request, "encyclopedia/error.html",{
"form":NewForm()
})
return redirect(reverse('page', args = [title]))
return render(request, "encyclopedia/newpage.html",{
"form1":Title(),
"form": NewForm()
})

You are probably getting the exception thrown in your return statement where you are instantiating a new Title object. This object only gets the cleaned_data attribute when is_valid method has been called upon. Hence you haven't called this on the new Title object and that is the reason why you are getting the error.

you use form = Title(request.POST), but the line after you check whether the request.method equals POST or not. i think yo should move that line inside the if statement

is_valid() it's a function
def new(request):
form = Title(request.POST)
if request.method == "POST":
if form.is_valid():
title = form.cleaned_data["title"]
text = form.cleaned_data["text"]
util.save_entry(title, text)
else:
return render(request, "encyclopedia/error.html",{
"form":NewForm()
})
return redirect(reverse('page', args = [title]))
return render(request, "encyclopedia/newpage.html",{
"form1":Title(),
"form": NewForm()
})

Related

How to fix a Django view that is not returning an HttpResponse Object? (CS50 Project 1)

I am receiving the following error when submitting a form.
ValueError at /edit_entry/hi/
The view encyclopedia.views.edit_entry didn't return an HttpResponse object. It returned None instead.
Here is the views.py that is triggering the error.
def edit_entry(request, title):
if request.method == "POST":
form = NewEditEntryForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
util.save_entry(title, content)
return HttpResponseRedirect("/wiki/" + title)
else:
form = NewEditEntryForm()
return render(request, "encyclopedia/edit_entry.html",{
"form": NewEditEntryForm(),
"title": title,
"content": util.get_entry(title)
})
What is the issue and how can I fix it?
(I also need help prepopulating the form with already existing data. I have tried using initial, but that has not worked. What is the best way to prepopulate the form with existing data?)
util.save_entry
def save_entry(title, content):
"""
Saves an encyclopedia entry, given its title and Markdown
content. If an existing entry with the same title already exists,
it is replaced.
"""
filename = f"entries/{title}.md"
if default_storage.exists(filename):
default_storage.delete(filename)
default_storage.save(filename, ContentFile(content))
sorry, I thought that you have a model.
# on util.py
def get_entry_content(title):
filename = f"entries/{title}.md"
return default_storage.open(filename).read()
# on views.py
def edit_entry(request, title):
if request.method == "POST":
form = NewEditEntryForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
util.save_entry(title, content)
return HttpResponseRedirect("/wiki/" + instance.title)
else:
content = util.get_entry_content(title)
initial_dict = {
"title" : title,
"content" : content,
}
form = NewEditEntryForm(initial=initial_dict)
return render(request, "encyclopedia/edit_entry.html", {
"form": form,
})
All right, I think if this is not doing what you want, i would test the save_entry function in the console, creating and updating to see if it works or not.

UnboundLocalError when submitting form in Django App

I am trying to submit a form but receiving an error:
UnboundLocalError at /create/
local variable 'spr' referenced before assignment
Below is the section of my views.py file that is highlighted in the error, specifically:
return HttpResponseRedirect("/%i" %spr.id)
def create(response):
if response.method == "POST":
form = CreateNewSprint(response.POST)
if form.is_valid():
n = form.cleaned_data["name"]
spr = Sprint(name=n)
spr.save()
response.user.sprint.add(spr)
return HttpResponseRedirect("/%i" %spr.id)
else:
form = CreateNewSprint()
return render(response, "main/create.html", {"form": form})
I am unsure of why this is happening, any pointers in the right direction would be greatly appreciated. If any other code/information is needed please let me know.
If the form.is_valid() returns False, then it will aim to evaluate return HttpResponseRedirect("/%i" %spr.id), but spr is never set in that case. You thus should in that case rerender the invalid form:
def create(response):
if response.method == 'POST':
form = CreateNewSprint(response.POST)
if form.is_valid():
n = form.cleaned_data['name']
spr = Sprint(name=n)
spr.save()
response.user.sprint.add(spr)
return HttpResponseRedirect('/%i' %spr.id)
else:
form = CreateNewSprint()
return render(response, 'main/create.html', {'form': form})
Note: You can make use of redirect(…) [Django-doc] and
determine the url based on the view name and the parameters. This is more safe and elegant than performing string formatting and
then wrap it in a HttpResponseRedirect object [Django-doc].

Why is My Django Form Executed Twice?

Can someone explain to me why form 2 executed twice? In another word, I would see 2 print statements, "Hello from form 2," in the console.
The first print statement occurred after I clicked "Submit" from form 1. Second print statement comes after the second "Submit" I clicked from form 2. How do I make it to only print once?
views.py
def form1 (request):
NameFormSet = formset_factory (NameForm, formset = BaseNodeFormSet, extra = 2, max_num = 5)
if request.method == 'POST':
name_formset = NameFormSet (request.POST, prefix = 'nameform')
if name_formset.is_valid ():
data = name_formset.cleaned_data
request.session ['data'] = data
return HttpResponseRedirect ('form2')
else:
name_formset = NameFormSet (prefix = 'nameform')
context = {'name_formset': name_formset}
return render (request, 'nameform/form1.html', context)
def form2 (request):
data = request.session ['data']
print ('Hello from form 2') # <==== This statement printed twice in the console
CheckBoxFormSet = formset_factory (CheckBox, extra = 2, max_num = 5)
if request.method == 'POST':
checkbox_formset = CheckBoxFormSet (request.POST, prefix = 'checkbox')
if checkbox_formset.is_valid ():
for i, form in enumerate (checkbox_formset.cleaned_data):
data [i].update (form) # Join cleaned data with original data
del request.session ['data']
context = {'data': data}
return render (request, 'nameform/success.html', context)
checkbox_formset = CheckBoxFormSet (prefix = 'checkbox')
context = {'checkbox_formset': checkbox_formset, 'data': data}
return render (request, 'nameform/form2', context)
Update 1:
The "print" statement is actually a backend method that processes the data obtained from form 1 and display it in form 2. Leaving where it is now would cause that method to process the information twice. I have no issue or error doing it this way but it's unnecessary.
For example:
def form2 (request):
data = request.session ['data']
n, errors = getInfo (data) # <==== This statement performed twice in the console
if request.method = 'POST':
....
if checkbox_formset.is_valid ():
for i, form in enumerate (checkbox_formset.cleaned_data):
data [i].update (form) # Join cleaned data with original data
n.process_new_data (data, errors)
del request.session ['data']
context = {'data': data, 'errors': error}
return render (request, 'nameform/success.html', context)
else:
checkbox_formset = CheckBoxFormset (prefix = 'checkbox')
context = {'data': data, 'errors': error}
return render (request, 'nameform/form2.html', context)
Update 2:
Since my explanation is a little long, allow me address Ale question here.
Yes, I fully understand why it processed twice. To briefly answer your question, putting getInfo inside 'POST' will give me a context, unbound error because of the context "errors" dictionary doesn't exist in the first redirect.
context = {'data': data, 'errors': errors}
I'd to update my post so that I can explain why I can't use your method. GetInfo takes the data from form1, processes it, and passes it on to form 2 to display. I could do all that in form1 but then I would have to redo it in form2 because form2 will not know what 'n' or 'errors' is without passing it through sessions. I'm just trying to see if there's a better way to do this.
The form2 view is run twice, once as a redirect from form1 which creates the form and renders the template, missing the if request.method == 'POST' part as this time around the request is a 'GET'.
When you submit form2 back to the same view method it prints the line you indicate again, this time the code in the if block executes as the request is a 'POST'.
The key is this line that redirects to the form2 view:
return HttpResponseRedirect ('form2')
You can debug this by including the stacktrace to you print statements:
import traceback
print ''.join(traceback.format_stack())

csv_import() takes exactly 1 argument (0 given)

Hey I'm trying to upload a csv file using a DJANGO view but I'm getting this error
csv_import() takes exactly 1 argument (0 given)
my code is
view
def csv_import(request, **kwargs):
if request.method == "POST":
form = DataInput(request.POST, request.FILES)
if form.is_valid():
form.save()
success = True
context = {"form": form, "success": success}
return render_to_response("imported.html", context,
context_instance=RequestContext(request))
else:
form = DataInput()
context = {"form": form}
return render_to_response("imported.html", context,
context_instance=RequestContext(request))
form
class DataInput(forms.Form):
file = forms.FileField()
def save(self):
records = csv.reader(self.cleaned_data["file"])
for line in records:
parts = Part()
parts.supplier_id = line[0]
parts.name = line[1]
parts.description = line[2]
parts.save()
url
url(r'^imported',views.csv_import(),name="imported")
any help would be appreciated
Try to pass views.csv_import without () as the second parameter to url.
You don't want to call it right away but tell url which function to call when a matching request comes in.

ModelForm For Registration HttpResponseError

First off, I know what the error means, I'm just confused on the configuration.
I'm getting an error of:
views.Registration didn't return an HttpResponse object
The issue is when I visit localhost/Register, I get the above error.
Q: If I want localhost/Register to show form from RegistrationForm() when it loads the register.html template within render() (at the bottom) when /Register is accessed. How do I do that? Do I need to create another view like /NewUser that I currently have specified? My thought was that render() was going to execute to show the template (with the form inside it) when viewing /Register
Code:
a view of:
def Registration(request):
RegForm = RegistrationForm(request.POST or None)
if request.method == 'POST':
if RegForm.is_valid():
clearUserName = RegForm.cleaned_data['userNm']
clearPass = RegForm.cleaned_data['userPass']
RegForm.save()
try:
return HttpResponseRedirect('/NewUser/?user=' + clearUserName)
except:
raise ValidationError('Invalid Request', code='300') ## [ TODO ]: add a custom error page here.
else:
RegForm = RegistrationForm()
return render(request, 'VA/reuse/register.html', {
'form': RegForm
})
You need to render something if the request is 'GET' instead of 'POST': ie.
def Registration(request):
RegForm = RegistrationForm(request.POST or None)
if request.method == 'POST':
if RegForm.is_valid():
clearUserName = RegForm.cleaned_data['userNm']
clearPass = RegForm.cleaned_data['userPass']
RegForm.save()
try:
return HttpResponseRedirect('/NewUser/?user=' + clearUserName)
except:
raise ValidationError('Invalid Request', code='300') ## [ TODO ]: add a custom error page here.
else:
RegForm = RegistrationForm()
return render(request, 'VA/reuse/register.html', {
'form': RegForm
})
else:
RegForm=RegistrationForm()
return render(request, 'template.html', {'formset': RegForm})
of course, you should change the context for your template, depending on whatever it is you need to render.
No, you should just move everything from the else onwards back one indentation level. Otherwise, nothing is returned if the request is not a POST.

Categories

Resources