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()
Related
In my form, I got a class named Cform which is subclassed to ConstanceForm Cform(ConstanceForm)
In my views.py
class ResetCView(FormView):
template_name = 'c.htm.jinja'
form_class = Cform
model = CModel
def form_valid(self.form):
form.cleaned['C_CODE'] = settings.C_CODE
form.save()
return HttpResponseRedirect(reverse('cview))
In my template:
<form method="post" action="{{url('c-reset')}}" name="form">
<button>Reset</button>
</form>
<form method="post" action="{{url('c-view')}}" name="form">
{{ form.as_p}}
</form>
My problem is it is not updating. Form is always invalid. I just want to reset my form or its database value to a specific data.
Probably the easiest way for you to handle this is to add a clean method in the form for that field and set it there
def clean_c_code(self):
self.cleaned_data['C_CODE'] = settings.C_CODE
return self.cleaned_data['C_CODE']
Although,
Do you really need it in the form at all if its always going to have the same value (just access the setting)
It might not be a good idea at all, settings should stay the same as when you first run the server
I'm trying to create a simple WTForms-based admin interface for an SQLAlchemy app, using Jinja2 templates.
I've read the docs of WTForms-Alchemy and I understand that it can auto-generate a form from my model just via a few lines of code, like:
class UserForm(ModelForm):
class Meta:
model = User
My problem is that even though I have this form auto-generated, I found no resource anywhere about how can I make it into a functional HTML page. There are a few snippets about rendering errors for fields, as well as some SO answers mentioning macros for rendering whole fields, but I found absolutely no resource about how to generate a full, functional form automatically.
// I understand that this is something what Flask-Admin might do already, I'm not using Flask so this is not a possibility unfortunately.
WTForms leaves it up to you to figure out how to you want to render out your form after you pass it into your template. The simplest way to render a form would be to just iterate through your form and render the fields. When a field (or its label) is called, it emits HTML.
<form action="/some_url" method="POST">
{% for field in form %}
{{ field.label() }}
{{ field() }}
{% endfor %}
<button type="submit" />
</form>
The macros provided here provide an automated way to generate HTML surrounding these fields.
You can use wtf.quick_form like this, in which case you'll have a totally generic form template. Mark up your db.Model members with info{} properties to set field display names etc
<form method="post" action="/{{route}}">
<fieldset>
{{ wtf.quick_form(form, button_map={'submit':'success'}) }}
<input class="btn btn-success" type="submit" value="Submit" />
<button type="button" class="btn">Cancel</button>
</fieldset>
</form>
Your form definition:
class MyobjectForm(BaseModelForm):
class Meta:
model = Myobject
Then your route handler looks like this:
#app.route('/myobject', methods=('GET', 'POST'))
def myobject_route():
obj = Myobject()
form = MyobjectForm(obj = obj)
if form.validate_on_submit():
form.populate_obj(obj)
db.session.add(obj)
db.session.commit()
return redirect(url_for('index'))
return render_template('form.j2', form=form, title='My Object', route='myobject')
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.
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/
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>