Suppose I have a TrueFalseQuestion model (which only has a question_text) in myproject/myapp/models.py, and I want it to be rendered as, let's say
<a>Question Text</a>
<input type="radio">True</input>
<input type="radio">False</input>
(HTML could be wrong, not important) , in this template, only Question Text part changes, the input forms are always constant. So how can I implement this behaviour in Django?
An example would be appreciated. Thanks !
In your views.py file of the app, add the following.
from django.views.generic import ListView
from models import TrueFalseQuestion
class QuestionsList(ListView):
queryset = TrueFalseQuestion.objects.all()
template_name = 'name_of_your_template'
Then inside your template, iterate over the object_list like this:
{%for ques in object_list%}
<a>{{ques.question_text}}</a>
<input type="radio">True</input>
<input type="radio">False</input>
{%endfor%}
Also, make sure to point your url to the view.
Related
been searching a lot for fixing my issue.. New to django and might be missing a very simple logic here and looking for some help..
I have created a form in html page called thispage.html as below:
<form action="{% url 'getvaluefromform' %}" method="POST">{% csrf_token %}
<input type="text" name='mytitle' placeholder="enter title">
<input type="submit" value="save">
</form>
then I updated views.py with the below code:
from django.shortcuts import render
def index(request):
return render(request,'thispage.html')
def getvaluefromform(request):
mytitle = request.POST.get('mytitle')
print(mytitle)
return render(request,'thispage.html')
finally my urls.py has this part:
from dhango.urls import path
from . import views
urlpatterns = [
path('',views.index,name='index'),
path('getvaluefromform',views.getvaluefromform,name='getvaluefromform')
]
Problem:
when I use this I am able to get the input vallue however the url is changing to '/getvaluefromform' and when I remove 'getvaluefromform' from the url section and just keep it '' then the code view index gets picked up.
Is there a way I can call the second function when button is clicked without moving to the new path. Please advise.
P.S - I am deliberately not using a model form because I want to build a raw sql query based on user input and then run the query to get the results/ create a new table on the database.
Django forms:
If you want to get POST data from a form without changing routes you have a very good example in the official documentation.
HTML forms:
If you're not into Django forms you can do as stated below.
def getvaluefromform(request):
if request.method == 'POST':
mytitle = request.POST.get('mytitle')
return render(request,'otherpage.html')
return render(request,'thispage.html')
What this will do is basically check if there's a POST request, get the form data and if there's a GET request, you'll just render the defined page.
If you must have two different routes, I suggest using Javascript.
How does one correctly override the styling of a single item in Django's model form {{form}} call. I cant seem to just overide the defualt behaviour and add my necessary style.
Specifically, I would like to add a simple slider that passes through some text to the view.
I have added an extra field to my form as follows:
class CreateTestForm(forms.ModelForm):
difficulty = forms.CharField()
class Meta:
model = Test
And the following in my html directly:
<form method="POST" action=""> {% csrf_token %}
{{ form|crispy }}
<strong>Difficulty</strong>
<input id="difficulty" type="text" value="" class="slider form-control" data-slider-min="0" data-slider-max="10"
data-slider-step="1" data-slider-value="[0,10]" data-slider-orientation="horizontal"
data-slider-selection="before" data-slider-tooltip="show" data-slider-id="blue">
</br>
<input type='submit' value='Create' class='btn'>
</form>
However, when I render the view, I get two difficulties inputs (one slider and one box). I understand that Django is creating the text box for me, but I assumed, giving my slider the same id would simply override it?
From my belief, I would also have to have the slider defined in the forms.py class for this form, else it is not accessible in cleaned_data in the view. Any ideas?
I'm not sure why you would assume that. But why not define the relevant attributes in the form in the first place, so that they get output automatically?
difficulty = forms.CharField(widget=forms.TextInput(attrs={"class": "slider form-control", "data-slider-min": "0"...}))
Or even better, use the Crispy API to let you declare those attributes (I don't use Crispy myself, but I know it gives you a lot of extra control.)
You can override the default widget, adding your class for styling like so:
from django import forms
class CreateTestform(forms.ModelForm):
class Meta:
model = Test
fields = ['difficulty'] # you don't need to define difficulty again,
# just get it from your model like in this example.
widget = {
'difficulty': forms.CharField(attrs={
'class': 'name-of-your-class',
'other-attribute': 'other-value',
}),
}
You can check for more here.
If you have too much styling to apply to your form, I suggest to render it manually and I know you use cripsy to avoid that, but it's a easier way, without limits, django is supposed to be used for backend, not frontend.
You can even render like this (supposing you have to render difficulty):
<input class="whatever-your-class-is" name="{{ form.difficulty.html_name }}" id="{{ form.difficulty.id_for_label }}">
If you look carefully, you found information about .html_name and .id_for_label, even .value here.
The Docs says, to display the form fields in template, i need to do this:
<form action="/search_for_book/">{% csrf_token %}
{{form.as_p}}
<input type="submit" value="Suchen" />
</form>
i did this. and this is my views.
def addbook(request):
form = AddBook()
return render(request,'searchbook.html',{'form':form})
this is my form. defined in forms.py and imported into views.py
class AddBook(forms.Form):
titel = forms.TextInput()
author = forms.TextInput()
why dont Form fields show up in template? I did almost the 1:1 copy from docs. Template shows only the button Suchen and nothing else. Docs doesnot say anything about Urlconf, do i have to do also?
The reason why is that you're defining a widget, which is merely a representation of a HTML input element, instead of defining a field in your forms.py
Do the following:
class AddBook(forms.Form):
titel = forms.CharField(widget=forms.TextInput())
author = forms.CharField(widget=forms.TextInput())
PS: don't blame django's docs - they are really excellent!
For the referencce on widgets, read here: https://docs.djangoproject.com/en/dev/ref/forms/widgets/
For the reference on fields, read here: https://docs.djangoproject.com/en/dev/ref/forms/fields/
Hello and thank you in advance. I have a django form that is not rendering on a template. The "submit" button renders, but the form doesn't. I have been staring at this code for about 6 hours and it is probably something very simple, I probably need another pair of eyes on it.
My Model:
#models.py
from django.db import models
from django.forms import ModelForm
class DraftInput(models.Model):
player_id = models.IntegerField(help_text = 'Input Player ID Number', max_length = 5)
def __unicode__(self):
return self.player_id
class DraftForm(ModelForm):
class Meta:
model = DraftInput
My views:
#views.py
from django.shortcuts import render_to_response
from simple.models import DraftInput
from simple.models import DraftForm
from django.template import RequestContext
#...
def draft_view(request):
if request.method == 'POST':
form = DraftForm(request.POST)
if form.is_valid():
form.save()
else:
form = DraftForm()
return render_to_response('simple/draft_input.html', {'form': form} )
My template:
#draft_input.html
#...
<h1>Draft Input</h1>
<h2>Draft</h2><br /><br />
<form method="POST" action="">
<table>{{ form }}</table>
<input type="submit" value="Draft Player" />
</form><br /><br />
#...
Thank you for your help.
Reading the answers thread, it seems you're still out of luck.
Try performing these commands in a django interactive shell (python manage.py shell). It's possible that an exception is thrown when you try to format the form. When an exception is thrown during the form generation in the template, you won't see much in the HTML; but a django shell usually unveils the culprit.
python manage.py shell
In [1]: from simple.models import DraftForm
In [2]: form = DraftForm()
In [3]: form.as_p()
You can either see the HTML generated here, or would catch an exception. This will tell you more about what you need to fix.
Either use {{ form.as_table }} or remove the <table></table> from around your form tag.
I think that it is a sign to move to generics classes :) Just try CreateView class
In your views.py file:
class CreateDraftInputView(CreateView):
model = DraftInput
template_name = "test/draftinput_form.html"
success_url = "/test/listdraft/"
Simple create template:
<form method="POST" action=".">
<table>
{% csrf_token %}
{{ form.as_table }}
<input type="submit" />
</table>
</form>
And very simple list of records in your urls.py:
, (r"^listdraft/$", ListView.as_view(model = DraftInput, template_name = "draftinput_list.html"))
Try {{ form.as_p }} for example. There are other shortcuts. You can also manually create the form. Have a look into the Django Docs : https://docs.djangoproject.com/en/dev/topics/forms/?from=olddocs
Try "form.as_p" or "form.as_table" instead of just "form" in your html file.
EDIT: check out the documentation and use one of their examples as a model: https://docs.djangoproject.com/en/dev/topics/forms/modelforms/
In your example, you define form parameters in your model, which may be incorrect. You want to leave form specific modifications, like help_text in the DraftForm class, now in the DraftInput model.
This is a simple issue, you should just replicate something from the docs and then work towards what you want.
Hope this helps.
Could not quickly find the root cause, but the fields in my form only show up when the variable declaration follows the conventional module.Class form. The issue might be somewhere in classloading order.
from simple import models
# ...
form = models.DraftForm()
I want to learn how can I add to template to my ModelForm i'm newbie. Below you can see my models.py, url.py and views.py:
My model.py looks like that:
from django.db import models
from django.forms import ModelForm
from django.contrib.auth.models import User
class Yazilar(models.Model):
yazi = models.CharField(max_length=200)
temsilci = models.ForeignKey(User)
class YaziForm(ModelForm):
class Meta:
model = Yazilar
My views.py function is below:
#login_required
def yazi_ekle(request):
yazim = YaziForm
return render_to_response('yazi/save.html', {'YaziForm': YaziForm})
My url.conf looks like below:
(r'^yazi/save/$', 'tryout.yazi.views.yazi_ekle'),
My question is about creating a form and what is that forms "action" parameter?
It seems to me that your problem is in the view, you should be doing something like this:
#login_required
def yazi_ekle(request):
yazim = YaziForm() # Look at the (), they are needed for instantiation
return render_to_response('yazi/save.html', {'YaziForm': yazim}) # Sending the form instance to the context, not the form class
Now, you have a variable named YaziForm in your template context. Django forms autorender to a bunch of table rows with the widgets as default, so in your file yazi/save.html, do this
<form method="post" action="">
{% csrf_token %}
<table>
{{YaziForm}}
</table>
<input type="submit" value="Submit Form"/>
</form>
That will render your form as a table automatically, though you have to add the logic for the form under POST.
You could in fact use <form action=""> since the url you want to post to is the same as the page you are on.
If you don't like that then as long as you have 'django.core.context_processors.request' in your TEMPLATE_CONTEXT_PROCESSORS in settings.py I think you could also do:
<form action="{{ request.path }}">
As always, see the docs :)
http://docs.djangoproject.com/en/1.1/ref/request-response/#django.http.HttpRequest.path
EDIT
In case, in the intervening year since this question was posted, the poster still hasn't tried to read the ModelForm docs... http://docs.djangoproject.com/en/1.2/topics/forms/modelforms/
Yes the view is wrong, you have instantiate the form. You also want some logic to handle the post data. If it's an edit view you probably also want the view to take an item id in the view args and have some logic to load that model instance.
eg:
#login_required
def yazi_ekle(request, id=None):
form_args = {}
if id is not None:
# edit an existing Yazilar
try:
yazilar = Yazilar.objects.get(pk=id)
except Yazilar.DoesNotExist:
return Http404('Yazilar not found')
form_args['instance'] = yazilar
# else create new Yazilar...
if request.POST:
form_args['data'] = request.POST
yazi_form = YaziForm(**form_args)
if yazi_form.is_valid():
yazilar = yazi_form.save(commit=True)
else:
yazi_form = YaziForm(**form_args)
return render_to_response('yazi/save.html',
{
'yazi_form': yazi_form
},
context_instance=RequestContext(request)
)
then in your urls.py something like:
(r'^yazi/ekle/(?P<id>\d+)?$', 'tryout.yazi.views.yazi_ekle'),
and in the template:
<form method="post" action="">
{% csrf_token %}<!-- required since Django 1.2 or later -->
<ul>
{{ yazi_form.as_ul }}
</ul>
<input type="submit" value="Submit Form"/>
</form>