how to get post data in django from iterating over different id - html

I am creating a app which is quetion and 4 options.Each time it gives different 5 quetions.using a id in html page i am creating a radio button for each choice.Now how can save this value by post method in database.
views.py
def result(request,id) :
if request.method=='POST':
selected_choice = request.POST['choice.id']
return redirect('list_view.html')
else:
return render (request,'create_view.html')
urls.py
path('result/<id>',views.result,name='result')
html page
<div>
{% for element in q %}
<h2>{{element.id}} .{{element.question}}</h2>
<form action="{% url 'app1:result' element.id %}" method="POST">
{% csrf_token %}
{% for choice in c %}
{% if element.id == choice.id %}
<input name="{{choice.id}}" type="radio" >{{choice.choice1}}<br>
<input name="{{choice.id}}" type="radio" >{{choice.choice2}}<br>
<input name="{{choice.id}}" type="radio" >{{choice.choice3}}<br>
<input name="{{choice.id}}" type="radio" >{{choice.choice4}}<br>
{% endif %}
{% endfor %}<br>
{% endfor %}
<input type="submit" value="submit">
</form>
</div>
models.py
class Question(models.Model):
question=models.CharField(max_length=100)
def __str__(self):
return self.question
class Choice(models.Model):
choice1=models.CharField(max_length=50)
choice2=models.CharField(max_length=50)
choice3 = models.CharField(max_length=50)
choice4 = models.CharField(max_length=50)
question = models.ForeignKey(Question, on_delete=models.CASCADE)

I would for sure try to go for Django forms for this. It is much easier. Check the answer from this question where it is detailed how to configure a radio button using Django forms.

You would like to change the input name of your choices from {{choice.id}} to choiceid-{{choice-id}}, it makes implementation easier.
For each input radio choice field, add a value attribute, for ex:
<input name="{{choice.id}}" type="radio" value="choice1">{{choice.choice1}}<br>
Create a ChoiceAnswer model with choice as foreign key.
for key in request.POST:
if key.startswith('choiceid-'):
# You can access user by request.user .
# Extract the choice here so that you can reference it in ChoiceAnswer instance.
choice = get_object_or_404(Choice, id=key.split('-')
if request.POST[key] == 'choice1':
# save data in your answer model here that choice1 has been selected.
elif request.POST[key] == 'choice2':
# save data in your answer model here that choice2 has been selected.

Related

Django, How to pass HTML form values to URL upon form submission?

The project have url as follows,
path('post/<str:state>/',SearchView.as_view(),name='search-data')
I have a HTML form, upon filling and submitting it supposed to pass filled form data to URL.
<form action={% url 'search-data'%} method="get" >
{% csrf_token %}
<input type="text" name="fname">
But it does not work as supposed to be.
When form submitted it gives below URL
http://127.0.0.1:8000/%7Burl?csrfmiddlewaretoken=2RZfZ4cxLB...
You don't have to pass <str:state> argument in your urlpatterns just pass path('post/search',SearchView.as_view(),name='search-data') or whatever you want but problem is when you pass an argument like this post/<str:state>/ than you have to specify that in your form action also
like this {% url 'search-data' state %} initialy you don't have any state so that's why you have to get the state name from your form so finnaly your code look like this
<form action={% url 'search-data'%} method="get" >
{% csrf_token %}
<input type="text" name="fname">
<input type="submit" value="search">
</form>
and than in your views you've to get it from request.GET method like this
def search(request):
state = request.GET.get('fname', None)
.... do whatever you want
return response_or_data

Django forms widgets Textarea is directly set to type hidden but need it visible

My problem is i set a form from a model to change the value of the field "description" of this model :
Model :
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
birth_date = models.DateField(null=True, blank=True)
profile_img = models.ForeignKey(Image,on_delete=models.CASCADE,related_name='images',null=True)
description = models.TextField()
Form :
class ChangeUserDescription(ModelForm):
class Meta:
model = Profile
fields = ['description']
widgets = {
'description': forms.Textarea()
}
labels = {
'description':'Description'
}
template :
<form method="post">
{% csrf_token %}
{{ form }}
<button type="submit">Save changes</button>
</form>
But in result of this code I obtain this :
<input type="hidden" name="csrfmiddlewaretoken" value="brsd4oO0qhMw2K8PyCIgSgEMqy7QFvEjTHaR6wTJmyWffJaCX5XyOMDLrGldZ3ji">
<button type="submit">Save changes</button>
The issue is that i get : type="hidden" in the input whereas i want it to be visible and i do not specified in the widgets that it must be hidden.
The hidden input field that you are referring to is the following:
<input type="hidden" name="csrfmiddlewaretoken" value="brsd4oO0qhMw2K8PyCIgSgEMqy7QFvEjTHaR6wTJmyWffJaCX5XyOMDLrGldZ3ji">
This is Django's CSRF token, which you have correctly included in your form, and should always be an <input type="hidden".
You have not shown us your template code, but as long as you correctly pass the form variable to your template, the following code should work:
<form method="post">
{% csrf_token %}
Please enter your description here: {{ form.description }}
<button>Submit</button>
{% if not form %}
You have forgot to add the <tt>form</tt> variable to your template!
{% endif %}
</form>

How can we use html <input type= ""> for Django model form?

using this for django model form, we cant create beautiful front end.
<form method="POST" action="">
{% csrf_token %}
<div class="esor">
Name: {{form.Name}}<br>
Class: {{form.Class}}<br>
Publisher: {{form.Publisher}}<br>
</div>
<input type="submit" value="submit">
</form>
Isn't there any ways so we can use html code like:
<form method="GET" action="#">
<input type="text" name="name" placeholder="Name of book">
</form>
instead of {{form.Name}} or {{form.as_p}}
Yes, you can get a beautiful interface that way, just pass the name you use in the form.py
Example:
forms.py
class NameForm(forms.ModelForm):
class Meta:
model = MyModel
fields = [
"whatever"
]
Html Template
<form method="POST">{% csrf_token %}
<input type="text" name="whatever" placeholder="Write whatever">
</form>
There are two approach I normally use:
Install widget tweaks, so you can customize your input easily:
{% load widget_tweaks %}
{{ form.Name|add_class:"css_class"|attr:"placeholder:Name of book" }}
Or 2, in your forms.py, set all the attributes you want for the field:
Name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Name of book'}))
You can do this by giving the name of your input element same as the name of your form field. And you can get name of your form field by displaying {{ form }} in html and then inspecting the form field in your browser and then the name attribute of that field will be name of the form field.

How to use POST in Django

I use Django 1.11.3 and python2.7
I want write a easy message board
and here is my code
<form name='my form' action='/talkpost/' method='POST'>
{% csrf_token %}
{% for m in moods %}
<input type='radio' name='mood' value='{{ m.status }}'>{{ m.status }}
{% endfor %}
<textarea name='user_post' rows=3 cols=70></textarea><br/>
<label for='user_id'>nicknameļ¼š</label>
<input id='user_id' type='text' name='user_id'>
<label for='user_pass'>password</label>
<input id='user_pass' type='password' name='user_pass'><br/>
<input type='submit' value='submit'>
<input type='reset' value='reset'>
<input type="hidden" name="ok" value="yes">
</form>
urls.py
url(r'^talkpost/', talkpost),
url(r'^talk/', talk),
talk is just for user to see the from and talkpost is for Django to get the post
request
views.py
def talk(request):
template = get_template('talk.html')
moods = Mood.objects.all()
message = 'Leave some message!'
html = template.render(locals())
return HttpResponse(html)
def talkpost(request):
template = get_template('talk.html')
if 'ok' in request.POST:
user_id = request.POST['user_id']
user_pass = request.POST['user_pass']
user_post = request.POST['user_post']
user_mood = request.POST['mood']
message = 'success!'
request_context = RequestContext(request)
request_context.push(locals())
html = template.render(request_context)
return HttpResponse(html)
I try using {% csrf_token %} and RequestContext But i still get CSRF token missing or incorrect.
I have no idea how to fix it
add the following:
from django.views.decorators.csrf import csrf_protect
your function will be:
#csrf_protect
def talkpost(request):
template = get_template('talk.html')
if 'ok' in request.POST:
user_id = request.POST['user_id']
user_pass = request.POST['user_pass']
user_post = request.POST['user_post']
user_mood = request.POST['mood']
message = 'success!'
request_context = RequestContext(request)
request_context.push(locals())
html = template.render(request_context)
return HttpResponse(html)
more info here:
https://docs.djangoproject.com/ko/1.11/ref/csrf/#how-to-use-it

Passing context on an html with both POST and GET options

I have a html page with various submit buttons:
<h3>Add Address</h3>
<form method="post">
{% csrf_token %}
...
<input type="submit" value="Add" name="_add_add">
</form>
<h3> Update values </h3>
<form method="post">
{% csrf_token %}
...
<input type="submit" value="Add" name="_update">
</form>
<h3>Address</h3>
<form method="get">
...display...
My view.py is:
def property(request):
if request.method == 'POST':
if '_update' in request.POST:
...update values...
elif '_add_add' in request.POST:
...add addres....
Context = {"name_for_template":"value"}
else:
... graph default values...
Context = {"name_for_template":"value"}
return render(request, 'address.html', context)
When there isn't a POST and simply a GET (like being redirected to the page), I get an CSRF error in the context (and it asked me to use request_context). Is it possible (and how) to automatically send a default context for the GET, and send a different context for POST without incurring the CSRF error?
you can try this edit code
def property(request):
context = {}
if request.method == 'POST':
if '_update' in request.POST:
...update values...
elif '_add_add' in request.POST:
...add addres....
context["name_for_template"]= "value"
else:
... graph default values...
context["name_for_template"]= "value"
return render(request, 'address.html', context)
if it doesn't work, share your code