I want to use a part of the data from the form to use in my HttpResponseRedirect method, but I can't seem to manipulate the data once I get it from the form.
view.py:
if request.method == 'POST':
form = ReviewForm(request.POST)
if form.is_valid():
form.save(commit=True)
joint = form.cleaned_data['place']
//Gets me the name of the joint.
//I need to clean up the name so I can use it in a URL
joint = joint.replace('_', ' ')
joint = joint.replace('00', "'")
joint_url = joint.replace('11', "/")
return HttpResponseRedirect('/burgers/place/' + joint_url)
But when someone submits a name like "Hotdog House " The name of the place is returned, and all of my cleaning doesn't stick. I would expect to get Hotdog_House - but I get Hotdog House.
You're using the replace method wrong: if you want to convert from a space to an underscore, you should put them in the other way round:
joint = joint.replace(' ', '_')
Also note that this code should really be in the form's clean_place method, so that the data is converted by the form itself.
Related
So I'm expanding on the official tutorial, and I'm trying to let a user create their own poll. I'm having trouble assigning the correct question_id to the choice, so the choice aligns in the database with the question and both can be read off. Here is my view:
def poll_create(request):
if request.method == "POST":
Qform = QuestionForm(request.POST)
Cform = ChoiceForm(request.POST)
if Qform.is_valid():
poll = Qform.save(commit=False)
poll.author = request.user
poll.pub_date = timezone.now()
poll.save()
if Cform.is_valid():
poll = Cform.save(commit=False)
poll.author = request.user
findid = Question.objects.all().order_by("-id")[0] ##Finds the id of the last question in database
poll.question_id = findid.id + 1
poll.save()
return redirect('polls:detail', pk=poll.pk)
else:
Qform = QuestionForm()
Cform = ChoiceForm()
return render(request, 'polls/create.html', {'Qform': Qform, 'Cform': Cform})
So the idea is to have a question form (Qform) which writes the question to the database, and then below on the webpage a choice form (Cform), which writes the answer to the database. I'm really confused about applying a question_id to the Cform. At the moment, I have this line:
findid = Question.objects.all().order_by("-id")[0] ##Finds the id of the last question in database
poll.question_id = findid.id + 1
Which seems like a very hacky attempt to find the last id and assign it to the next one. It doesnt line up because the poll.pk has a different value. I'm at a loss here and don't really understand what's going on. Any help would be appreciated.
Your code is a bit confusing because you are using the variable poll for questions and choices. It would be better to use question and choice instead.
You should check that both forms are valid before you start saving, otherwise you can end up with a question without a choice if the question form is valid but the choice form is invalid.
After you have saved the question, you can get the id with question.id, and you can assign the question to the choice object. There is no need to do a query to find the latest question id.
Putting that together, you have something like:
if Qform.is_valid() and Cform.is_valid():
question = Qform.save(commit=False)
question.author = request.user
question.pub_date = timezone.now()
question.save()
choice = Cform.save(commit=False)
choice.author = request.user
choice.question = question
choice.save()
return redirect('polls:detail', pk=question.pk)
Note also that it's recommended to use lowercase question_form and choice_form, for the form instances, and uppercase QuestionForm and ChoiceForm for the classes.
i'm new to django so i'm sorry for my newbie question
i have a model and i need to let user edit data inside it using django forms or any other way.
look at the image above , i want to show this form ready populated with the data and let user update it.
what is the best way to do this ?
EDIT : here is my views.py code
def exam_Edit(request,examName,number=0):
numner = int(number)
number = int(number)
questionNo = int(numner)
Myexam = models.Exam.objects.get(name = examName)
QuestionsAll = models.Question.objects.filter(exam = Myexam)
myQeustion = Question.objects.filter(exam = Myexam)[nextQuestion]
answer1 = models.Asnwers.objects.filter(question=myQeustion)[0]
answer2 = models.Asnwers.objects.filter(question=myQeustion)[1]
answer3 = models.Asnwers.objects.filter(question=myQeustion)[2]
answer4 = models.Asnwers.objects.filter(question=myQeustion)[3]
# HERE IS MY PROBLEM : the line below creates a form with a data but it doesn't save it to the save object
form = QuestionsEditForm(initial = {'questionText':myQeustion.__unicode__() , 'firstChoiceText':answer1.__unicode__(),'secondChoiceText':answer2.__unicode__(),'thirdChoiceText':answer3.__unicode__(),'forthChoiceText':answer4.__unicode__()})
if request.method =='POST':
#if post
if form.is_valid():
questionText = form.cleaned_data['questionText']
Myexam = Exam.objects.get(name = examName)
myQeustion.questionText = form.cleaned_data['questionText']
answer1.answerText = form.cleaned_data['firstChoiceText']
answer1.save()
answer2.answerText = form.cleaned_data['secondChoiceText']
answer2.save()
answer3.answerText = form.cleaned_data['thirdChoiceText']
answer3.save()
answer4.answerText = form.cleaned_data['forthChoiceText']
answer4.save()
variables = RequestContext(request, {'form':form,'examName':examName,'questionNo':str(nextQuestion)})
return render_to_response('exam_edit.html',variables)
please help
Assuming you are using a ModelForm, use the instance keyword argument, and pass the model you are updating.
So, if you have MyModel and MyModelForm (the latter of which must extend django.forms.ModelForm), then your code snippet might look like:
my_record = MyModel.objects.get(id=XXX)
form = MyModelForm(instance=my_record)
And then, when the user sends back data by POST:
form = MyModelForm(request.POST, instance=my_record)
Incidentally, the documentation for ModelForm is here: http://docs.djangoproject.com/en/1.8/topics/forms/modelforms/
I have a django form and on my view function I do this :
search_packages_form = SearchPackagesForm( data = request.POST )
I would like to overwrite a form field called price which is decleared as such :
price = forms.ChoiceField( choices = PRICE_CHOICES, required = False,widget = forms.RadioSelect )
I would like to overwrite the form field before calling search_packages_form.is_valid()
I thought of doing :
search_packages_form.data['price'] = NEW_PRICE
But it does not work. Any ideas ?
Probably not the Django way but based on https://stackoverflow.com/a/17304350/2730032 I'm guessing the easiest way to change your form value before validation is to do something like the following:
def search_packages_view(request):
if request.method == 'POST'
updated_request = request.POST.copy()
updated_request.update({'price': NEW_PRICE})
search_packages_form = SearchPackagesForm(updated_request)
if search_packages_form.is_valid():
# You're all good
This works but I'd be interested if anyone has another way that seems more in line with Django, or if there isn't: then an explanation about why.
one trick for what you want is to do it like this:
changed_data = dict(request.POST)
changed_data['price'] = NEW_PRICE
search_packages_form = SearchPackagesForm(data = changed_data)
My solution is build on an earlier proposal. It is a working solution, which can be used in several cases.
#Milad Khodabandehloo
had a tricky solution to solve the problem.
changed_data = dict(request.POST)
changed_data['price'] = NEW_PRICE
search_packages_form = SearchPackagesForm(data = changed_data)
as #The EasyLearn Academy commented: it does not allow you to access actual data submitted in form.
This is because the request.POST is immutable.
But there is a solution to the problem - just have to be more tricky.
This solution is only good if a reference to the object is enough for the certain cause. It leaves the object itself the same.
# write object to variable (data)
data = request.POST
# set to mutable
data._mutable = True
# modify the values in data
data[modified_field] = new_value
# set mutable flag back (optional)
data._mutable = False
Hope it's useful!
form.is_valid() runs through your form's (and model's in case of a ModelForm) clean method's, returning True or False
If you plan on changing form data you can do it within the general clean method or at field level, e.g.
class YourForm(DerivingClass):
# regular stuff
def clean_<ATTR>(self):
# here
return self.cleaned_data
def clean(self):
# or here
return super(YourForm, self).clean()
I tried this, but there is no update done in django.
def update_product(request):
a= ProductForm(instance=Product.objects.get(product_id =2))#static id
render_to_response('profiles/updateproduct.html',{'form': a},RequestContext(request))
if request.method == "POST":
form = ProductForm(request.POST, instance=a)
if form.is_valid():
j=form.save(commit=False)
j.save
confirmation_message = "product information updated successfully!"
return HttpResponse("hhhh")
else:
form = ProductForm( instance = a )
You never actually call the model's save method since you are missing (). you must supply these in order to call the method.
j = form.save(commit=False)
j.save()
As a side note, since you are not doing anything to the model before saving it, you can simply replace these two lines with
j = form.save()
no real need here for the commit=False part.
I'm working with a django form, and I have a choice field. I think the problem may be that the choices are fetched dynamically, and right now there's only one value. I'm getting the TemplateSyntaxError: too many values to unpack. Some of the other posts seem to say that having only one value is a problem, so i adjusted my function that fetches the choices, and changed it so it added to blank options at the beginning, just as a test. However this brought up another error: need more than 0 values to unpack
Not really sure what to do about this, because even if there is only one value, I need it to still execute.
Form:
class UploadFileForm(forms.Form):
category = forms.ChoiceField(get_category_list())
file = forms.FileField()
Category Fetch Function:
def get_category_list():
cats = [(), ()]
for i in os.listdir(settings.MEDIA_ROOT + '/forms'):
cats.append(i)
return cats
Template Section:
<div id='addformdialog' title='Add Form'>
{{ form.as_p }}
</div>
View:
def fm(request):
if request.session['SecurityLevel'] != 2:
return HttpResponse('Access Denied!')
if request.method == 'POST':
form = UpoadFileForm(request.POST, request.FILES)
if form.is_valid():
destination = open(settings.MEDIA_ROOT + "/forms/" + request.POST['category'] + "/" + request.FILES['file'].name, 'wb+')
for chunk in request.FILES['file'].chunks():
destination.write(chunk)
destination.close()
form = UploadFileForm()
return render_to_response('admin/fm.html', {'categories':cats, 'form':form, 'uploadsuccess':True})
else:
cats = get_category_list()
form = UploadFileForm()
return render_to_response('admin/fm.html', {'categories':cats, 'form':form})
choices is supposed to be an iterable of 2-tuples. You are only appending a single string, which is causing chaos due to how strings and tuples interact (I'll give you details if you really care). Append 2-tuples instead.