Reputation: 2735
I'm new to Django web dev, managed to setup a toy project following this tutorial.
However I found the Django official documentation as well as this tutorial are quite confusing, hard for me to follow, especially the template context variables.
For example, in xxapp/views.py
we defined a few views as follows,
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from catalog.models import Author
class AuthorCreate(CreateView):
model = Author
fields = '__all__'
initial = {'date_of_death': '05/01/2018'}
class AuthorUpdate(UpdateView):
model = Author
fields = ['first_name', 'last_name', 'date_of_birth', 'date_of_death']
class AuthorDelete(DeleteView):
model = Author
success_url = reverse_lazy('authors')
Then in templates, we have this
{% extends "base_generic.html" %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
<table>
{{ form.as_table }} <!-- WHERE IS THIS "FORM" FROM? -->
</table>
<input type="submit" value="Submit">
</form>
{% endblock %}
I understand this template file, except for one thing, where is the form.as_table
from, and what is it??
I'm aware that, if we use some built-in class views or models, we might have some context data for free, but where do I lookup them, I searched on Django but found nothing.
Upvotes: 1
Views: 2972
Reputation: 20692
You're using generic class-based views, which come with a lot of functionality baked in. The best source to look them up is this one.
If you look at the CreateView
for example (Edit -> CreateView), you'll see that the get()
method, which is the first method called when you just fetch the page using GET, just calls render_to_response()
with context data fetched from get_context_data()
.
And inside get_context_data()
, we add a form
context variable to the context, which is assigned to get_form()
. etc...
Same with the post()
method, where first the form
is fetched, checked for validity and if not valid, the form_invalid()
method renders the template with the form
in its context.
You can follow the same with UpdateView
and DeleteView
, they are very similar. Most of the form handling code actually comes from the FormMixin
class.
When creating your own views, subclassing Django's generic views, you'll find that sometimes you can't use a view, but you can use the mixins (e.g. FormMixin
or ModelFormMixin
).
So form
in your template is the ModelForm
for the Author
model you specified in your generic views. The view is auto-generating that form from the model using a modelform_factory
, with the fields you specified with fields
. Since it's added as 'form'
key to the context used to render the template, you can access it with {{ form }}
. {{ form.as_table }}
will render the HTML for this form in a <table>
, as described here.
If you don't like how the form looks like and want to customise some of the fields (and can't do that by just changing the template), you would need to create your own form, tell your view about it by setting the form_class
attribute and removing the fields
attribute (the fields would be specified in your form), as described by @drew in his response.
Upvotes: 2
Reputation: 781
"form" is a variable you need to pass from your view to your template.
You should create a forms.py file to set up all of your forms.
In this file you would create a simple form like so:
from django import forms
class NameForm(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100)
And then in your view you should import the form and then set the "form" variable as such:
form = NameForm()
Or if you have posted data:
form = NameForm(request.POST)
So once you have passed this variable to the template, you can either call the entire form as you have using "form.as_table"
Or you can call individual form fields, such as:
{{ form.your_name.label }}
{{ form.your_name }}
{{ form.your_name.errors }}
See this help doc on the Django site for more information: https://docs.djangoproject.com/en/2.1/topics/forms/#the-form-class
Upvotes: 2