Difference between revisions of "Python-Django/C2/Creating-Forms-in-Django/English"
Pravin1389 (Talk | contribs) (Created page with ".") |
Nancyvarkey (Talk | contribs) |
||
(One intermediate revision by one other user not shown) | |||
Line 1: | Line 1: | ||
− | . | + | Django/C2/Creating-Forms-in-Django/English |
+ | |||
+ | '''Title of script: '''Creating Forms in Django | ||
+ | |||
+ | '''Keywords: '''Video tutorial, Django views, Django Forms | ||
+ | |||
+ | |||
+ | |||
+ | {| border=1 | ||
+ | |- | ||
+ | || Visual cue | ||
+ | || Narration | ||
+ | |- | ||
+ | || Slide: Creating Forms in Django | ||
+ | || Hello and Welcome to the spoken tutorial on “'''Creating Forms in Django'''” | ||
+ | |- | ||
+ | || Slide: Learning Objectives | ||
+ | || In this tutorial, we will learn to: | ||
+ | |||
+ | * Create a '''Django form''' | ||
+ | * Create '''views '''to handle '''form submission''' | ||
+ | |- | ||
+ | || Slide: System Requirements | ||
+ | || To record this tutorial, I am using | ||
+ | |||
+ | * '''Ubuntu Linux''' 16.04 OS | ||
+ | * '''Python''' 3.5 | ||
+ | * '''Python 3.4-venv '''or higher | ||
+ | * '''gedit Text Editor '''and | ||
+ | * '''Firefox web browser''' | ||
+ | |||
+ | |- | ||
+ | || Slide: Prerequisites | ||
+ | || To follow this tutorial, you need to know | ||
+ | |||
+ | * How to create''' models '''and '''HTML templates''' in''' Django''' | ||
+ | * If not, then please go through the prerequisite tutorials in this website. | ||
+ | |- | ||
+ | || Slide: Forms | ||
+ | || | ||
+ | * '''Forms''' are used to get '''data''' from the user | ||
+ | * The '''data''' is processed on the '''server''' side | ||
+ | * Users can provide the '''data''' using '''form elements''' like '''text fields, options,''' etc. | ||
+ | * '''Django '''has '''inbuilt libraries''' that build '''forms''' easily | ||
+ | |||
+ | |- | ||
+ | || Open a Terminal window | ||
+ | |||
+ | |||
+ | Press CTRl+ALT+T simultaneously | ||
+ | || Let us open the '''terminal '''by pressing '''Ctrl, Alt''' and '''T '''keys simultaneously on the keyboard. | ||
+ | |- | ||
+ | || [Terminal] | ||
+ | |||
+ | cd '''my-django '''[Enter] | ||
+ | || Now using the '''cd command''', go to the folder '''my hyphen django '''which we created earlier. | ||
+ | |- | ||
+ | | [Terminal] | ||
+ | |||
+ | Type source myapp_env/bin/activate | ||
+ | |||
+ | and press Enter | ||
+ | | Activate the '''virtual environment myapp underscore env''' | ||
+ | |- | ||
+ | || [Terminal] cd '''mysite''' [Enter] | ||
+ | || Then go to the '''mysite''' folder using the '''cd command.''' | ||
+ | |- | ||
+ | || | ||
+ | || Here onwards, please remember to press the '''Enter''' key after typing each '''command'''. | ||
+ | |- | ||
+ | || [Terminal] | ||
+ | Type gedit blog/forms.py & [Enter] | ||
+ | || Let us now create a '''form''' in '''Django''' using '''models.''' | ||
+ | |||
+ | To do so, create a file '''forms dot py''' in the '''blog''' directory. | ||
+ | |||
+ | Type the '''command''' as shown. | ||
+ | |- | ||
+ | || [forms.py]Type: | ||
+ | |||
+ | from blog.models import Blog, Article | ||
+ | |||
+ | from django import forms | ||
+ | |||
+ | |||
+ | class BlogForm(forms.ModelForm): | ||
+ | |||
+ | class Meta: | ||
+ | |||
+ | model = Blog | ||
+ | |||
+ | fields = ['name'] | ||
+ | |||
+ | class ArticleForm(forms.ModelForm): | ||
+ | |||
+ | class Meta: | ||
+ | |||
+ | model = Article | ||
+ | |||
+ | fields = ['title', 'body', 'draft'] | ||
+ | || We are now in '''forms.py '''file. | ||
+ | |||
+ | Type the code as shown here. | ||
+ | |||
+ | |- | ||
+ | || [forms.py] Highlight | ||
+ | |||
+ | |||
+ | '''class BlogForm(forms.ModelForm): ''' | ||
+ | |||
+ | '''class ArticleForm(forms.ModelForm): ''' | ||
+ | || '''Django''' provides a '''class ModelForm''' to create a '''Form''' from a '''Model.''' | ||
+ | |||
+ | |||
+ | The '''Form''' is generated using the '''model definition'''. | ||
+ | |- | ||
+ | || [forms.py] Highlight | ||
+ | |||
+ | '''class Meta: ''' | ||
+ | || To provide '''data''' to the '''Form class''', we are using an inner '''class Meta.''' | ||
+ | |- | ||
+ | || [forms.py] Highlight | ||
+ | |||
+ | '''model = Blog''' | ||
+ | || We are assigning the '''Blog model''' which is used to generate '''Form.''' | ||
+ | |- | ||
+ | || [forms.py] Highlight | ||
+ | |||
+ | '''fields = ['name']''' | ||
+ | || In '''Meta class, Fields attribute''' is used to select the '''fields''' to use in the '''form.''' | ||
+ | |- | ||
+ | || [forms.py] Highlight | ||
+ | |||
+ | '''class ArticleForm(forms.ModelForm): | ||
+ | |||
+ | class Meta: | ||
+ | |||
+ | model = Article fields = ['title', 'body', 'draft']''' | ||
+ | || Similarly we have defined an inner '''class '''named''' Meta '''with '''fields '''for the '''Article Form.''' | ||
+ | |- | ||
+ | || [forms.py] Highlight | ||
+ | |||
+ | '''from blog.models import Blog, Article''' | ||
+ | || Here, we have imported our '''models, Blog '''and '''Article.''' | ||
+ | |- | ||
+ | || [forms.py] Highlight | ||
+ | |||
+ | '''from django import forms''' | ||
+ | || To create '''django forms''', we need to import '''forms '''from '''Django.''' | ||
+ | |- | ||
+ | || [forms.py] Highlight the complete code | ||
+ | || Now, we have defined '''Django form''' using '''models.''' | ||
+ | |- | ||
+ | | Press Ctrl+S | ||
+ | | Save the file. | ||
+ | |- | ||
+ | | Switch to Terminal | ||
+ | | Switch back to the '''terminal''' to create a '''template''' file to '''call''' our '''Django form.''' | ||
+ | |- | ||
+ | || [Terminal] | ||
+ | |||
+ | Type gedit blog/templates/add_blog.html & [Enter] | ||
+ | || Create an '''HTML''' file '''add underscore blog '''in '''templates''' directory. | ||
+ | |||
+ | Type the '''command''' as shown. | ||
+ | |- | ||
+ | || [add_blog.html]Type: | ||
+ | |||
+ | |||
+ | <html> | ||
+ | |||
+ | <body> | ||
+ | |||
+ | <form action="" method="POST"> | ||
+ | |||
+ | {% csrf_token %} | ||
+ | |||
+ | <nowiki> {{ form }} </nowiki> | ||
+ | |||
+ | <input type="submit" value="Add Blog" /> | ||
+ | |||
+ | </form> | ||
+ | |||
+ | </body> | ||
+ | |||
+ | </html> | ||
+ | || We are now in '''add_blog.html''', | ||
+ | |||
+ | |||
+ | Type the code as shown here. | ||
+ | |- | ||
+ | || [add_blog.html] Highlight | ||
+ | |||
+ | '''{% csrf_token %}''' | ||
+ | || '''CSRF - Cross Site Request Forgery Protection''' | ||
+ | |||
+ | We have to use the '''csrf_token tag''' in a '''template''' which uses the '''form POST request.''' | ||
+ | |||
+ | '''Django''' provides '''built-in CSRF''' protection to protect the '''server''' from malicious websites. | ||
+ | |- | ||
+ | || [add_blog.html] Highlight | ||
+ | |||
+ | ''' <nowiki> {{ form }} </nowiki>''' | ||
+ | || Here we have included our '''context variable''' to display our '''Django Form.''' | ||
+ | |- | ||
+ | || [add_blog.html] Highlight | ||
+ | |||
+ | '''<input type="submit" value="Add Blog" />''' | ||
+ | || Here, we have created a button to submit the '''form.''' | ||
+ | |- | ||
+ | || [add_blog.html] Highlight the complete code | ||
+ | || We have created a '''HTML template''' to use a '''form''' passed through '''context'''. | ||
+ | |- | ||
+ | | Press Ctrl+S | ||
+ | | Save the file. | ||
+ | |- | ||
+ | | Switch to Terminal | ||
+ | | Switch to the '''terminal'''. | ||
+ | |- | ||
+ | || [Terminal] | ||
+ | |||
+ | Type gedit blog/views.py & [Enter] | ||
+ | || Open the file '''views.py '''to use this '''template'''. | ||
+ | |||
+ | |||
+ | Type the '''command''' as shown. | ||
+ | |- | ||
+ | || [views.py]: | ||
+ | |||
+ | |||
+ | from django.shortcuts import render | ||
+ | |||
+ | from django.http import HttpResponse | ||
+ | |||
+ | from .models import Blog, Article | ||
+ | |||
+ | '''from blog.forms import BlogForm, ArticleForm''' | ||
+ | |||
+ | |||
+ | <nowiki># Create your views here.</nowiki> | ||
+ | |||
+ | |||
+ | def index(request): | ||
+ | |||
+ | return HttpResponse("Hello World") | ||
+ | |||
+ | |||
+ | '''def get_blogs(request):''' | ||
+ | |||
+ | '''blogs = Blog.objects.all()''' | ||
+ | |||
+ | '''context = {'blogs': blogs}''' | ||
+ | |||
+ | '''return render(request, 'blog/blogs.html', context)''' | ||
+ | |||
+ | |||
+ | '''def add_blog(request):''' | ||
+ | |||
+ | '''if request.method == 'POST':''' | ||
+ | |||
+ | '''form = BlogForm(request.POST)''' | ||
+ | |||
+ | '''if form.is_valid():''' | ||
+ | |||
+ | '''form.save()''' | ||
+ | |||
+ | '''return HttpResponse("Blog created")''' | ||
+ | |||
+ | '''else:''' | ||
+ | |||
+ | '''context = {'form': form}''' | ||
+ | |||
+ | '''return render(request, 'add_blog.html', context)''' | ||
+ | |||
+ | '''context = {'form': BlogForm()}''' | ||
+ | |||
+ | '''return render(request, 'add_blog.html', context)''' | ||
+ | || We are now in '''views.py '''file. | ||
+ | |||
+ | |||
+ | Type the code as shown here. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Import the '''BlogForm''' and '''ArticleForm''' | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Update the '''get_blogs function'''. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Next to the '''get_blogs function''', let us add '''add_blog function'''. | ||
+ | |||
+ | |||
+ | Type the code as shown here. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Here we have modified the''' function get_blog '''to get '''blog objects.''' | ||
+ | |||
+ | |||
+ | Also, we have defined a '''function add_blog.''' | ||
+ | |||
+ | |||
+ | |||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | '''if request.method == 'POST': ''' | ||
+ | || If this is a '''POST request''', we need to process the '''form data.''' | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | |||
+ | '''form = BlogForm(request.POST) ''' | ||
+ | || We have created an '''instance''' of the '''BlogForm class object''' using the '''data''' from the '''POST request.''' | ||
+ | |||
+ | |||
+ | All the '''fields''' from the '''form''' are in '''request.POST''' | ||
+ | |- | ||
+ | || [views.py] Highlight''' ''' | ||
+ | |||
+ | '''from blog.forms import BlogForm''' | ||
+ | || We have '''imported''' the '''BlogForm '''from our '''blog’s form.''' | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | |||
+ | '''if form.is_valid(): ''' | ||
+ | || Next, '''is_valid() method''' is used to check whether the entered '''data''' is valid or not. | ||
+ | |||
+ | If the '''data''' is valid then '''is_valid() function''' returns '''True'''. | ||
+ | |||
+ | Otherwise it returns '''False.''' | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | '''else part''' of def add_blog(request) | ||
+ | || In the '''Else statement, '''when the '''data''' is empty or invalid, it will return the '''form''' with errors. | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | '''form.save()''' | ||
+ | | When the '''form data''' is valid, we '''save''' a new '''Blog object''' from the '''form.''' | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | '''return HttpResponse("Blog created")''' | ||
+ | || After successful addition of the '''blog''', let’s '''return''' something. | ||
+ | |||
+ | |||
+ | So the '''return statement''' returns '''HttpResponse '''with the '''string “Blog created”.''' | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | '''context = {'form': BlogForm()}''' | ||
+ | || If the '''request''' is '''GET_ request''', then this will be executed. | ||
+ | |||
+ | An empty '''form instance''' of '''BlogForm''' is created. | ||
+ | |||
+ | Then, the '''form instance''' is added to '''context'''. | ||
+ | |||
+ | This '''context''' will be provided to the '''HTML template '''while rendering. | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | '''form = BlogForm(request.POST)''' | ||
+ | || This is what will happen when a '''form''' is '''submitted''' using a '''POST request'''. | ||
+ | |||
+ | A '''form instance''' is created and data from the '''request''' is populated with it. | ||
+ | |||
+ | This is called “'''binding data to the form'''”. | ||
+ | |||
+ | It is now a '''bound form''' | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | '''from django.shortcuts import render''' | ||
+ | |||
+ | '''from django.http import HttpResponse''' | ||
+ | |||
+ | '''from .models import Blog, Article''' | ||
+ | || Here we can see that, the necessary '''modules''' have already been '''imported'''. | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | '''def add_blog(request) '''section | ||
+ | || We have added a '''function''' in our '''views''' to '''add Blog '''with use of '''Form data.''' | ||
+ | |- | ||
+ | | Press Ctrl+S | ||
+ | | Save the file. | ||
+ | |- | ||
+ | | Switch to Terminal | ||
+ | | Switch to the '''Terminal'''. | ||
+ | |- | ||
+ | || [Terminal] | ||
+ | |||
+ | Type gedit blog/urls.py & [Enter] | ||
+ | |||
+ | || Now, we will insert the path in the '''URL configuration.''' | ||
+ | |||
+ | Type the '''command''' as shown. | ||
+ | |- | ||
+ | || [urls.py] | ||
+ | |||
+ | Type path('add_blog/', views.add_blog, name='add_blog'), | ||
+ | || We are now in '''urls.py''' file in '''blog app. ''' | ||
+ | |||
+ | Insert the new path as shown here. | ||
+ | |- | ||
+ | || [urls.py] | ||
+ | || We have added the path in '''blog app Urls.''' | ||
+ | |||
+ | And there are no changes in the '''root Urls'''. | ||
+ | |- | ||
+ | | Press Ctrl+S | ||
+ | | Save the file. | ||
+ | |- | ||
+ | | Switch to Terminal | ||
+ | | Switch to the '''Terminal'''. | ||
+ | |- | ||
+ | || [Terminal] | ||
+ | |||
+ | Press CTRL+SHIFT+T | ||
+ | || For our convenience, let us run the '''Django server''' in a separate '''terminal'''. | ||
+ | |||
+ | Press '''Shift, Ctrl '''and '''T '''keys simultaneously. | ||
+ | |- | ||
+ | || [Terminal Tab 2]Type: cd .. | ||
+ | |||
+ | Type source myapp_env/bin/activate | ||
+ | |||
+ | and press Enter | ||
+ | || In the new '''terminal tab''', go to '''my-django''' directory using the '''cd command.''' | ||
+ | |||
+ | Activate the '''virtual environment.''' | ||
+ | |- | ||
+ | || [Terminal tab 2] type cd mysite | ||
+ | |||
+ | Type python manage.py runserver [Enter] | ||
+ | || Now go to the '''mysite''' folder using '''cd command ''' | ||
+ | |||
+ | Start the '''server.''' | ||
+ | |- | ||
+ | || Open a browser and type | ||
+ | |||
+ | http://localhost:8000/blogs/add_blog | ||
+ | || Now we will call the '''view function add underscore blog.''' | ||
+ | |||
+ | Open the '''web browser''', and type the '''URL''' as shown and press '''Enter.''' | ||
+ | |- | ||
+ | || [browser] | ||
+ | Point to the form | ||
+ | || Here, we see a '''form''' with a labelled text '''Name'''. | ||
+ | |||
+ | Along with the '''input textbox''' and a '''Submit''' button. | ||
+ | |- | ||
+ | || [browser] (Cursor at text box) | ||
+ | |||
+ | press space key | ||
+ | || Let us first try with some '''invalid data.''' | ||
+ | |||
+ | In the textbox enter '''spaces''' by pressing '''Space''' key multiple times. | ||
+ | |- | ||
+ | || [browser] Click '''Add Blog''' | ||
+ | || Click on the '''Add Blog''' button to save. | ||
+ | |- | ||
+ | || [browser] | ||
+ | |||
+ | (pointing to the error message) | ||
+ | || Here, we see an error message '''“This field is required.”''' | ||
+ | |||
+ | So the '''blog''' is not created with invalid '''data'''. | ||
+ | |- | ||
+ | || [gedit] blog/views.py highlight | ||
+ | |||
+ | if form.is_valid():... | ||
+ | |||
+ | else: | ||
+ | |||
+ | context = {'form': form} | ||
+ | |||
+ | return render(request, 'add_blog.html', context) | ||
+ | || In this way we can handle the invalid '''data'''. | ||
+ | |||
+ | |||
+ | We check if the '''form''' is valid or not and handle the '''request''' accordingly. | ||
+ | |- | ||
+ | || [browser] (Cursor at text box) | ||
+ | |||
+ | Type '''MY BLOG''' | ||
+ | || Now, let us type '''MY BLOG '''in the text box. | ||
+ | |- | ||
+ | || [browser] | ||
+ | |||
+ | Click '''Add Blog''' | ||
+ | || Click on the '''Add Blog''' button to save the '''Blog.''' | ||
+ | |- | ||
+ | || [browser] | ||
+ | |||
+ | (pointing to the web page) | ||
+ | || Now, after '''submission''', we get the response as '''Blog created.''' | ||
+ | |- | ||
+ | || Switch to views.py file from browser | ||
+ | || Let us now move to our '''views.py '''file to edit the existing '''Blog.''' | ||
+ | |- | ||
+ | || [views.py]Type: | ||
+ | |||
+ | |||
+ | def add_blog(request, blog_id=None): | ||
+ | |||
+ | if blog_id: | ||
+ | |||
+ | blog = Blog.objects.get(id=blog_id) | ||
+ | |||
+ | else: | ||
+ | |||
+ | blog = Blog() | ||
+ | |||
+ | if request.method == 'POST': | ||
+ | |||
+ | form = BlogForm(request.POST, instance=blog) | ||
+ | |||
+ | if form.is_valid(): | ||
+ | |||
+ | form.save() return | ||
+ | |||
+ | get_blogs(request) else: | ||
+ | |||
+ | context = {'form': form} | ||
+ | |||
+ | return render(request, 'add_blog.html', context) | ||
+ | |||
+ | blog_form = BlogForm(instance=blog) | ||
+ | |||
+ | context = {'form': blog_form, 'blog': blog} | ||
+ | |||
+ | return render(request, 'add_blog.html', context) | ||
+ | || Modify the '''function add_blog '''in the '''views.py '''file as shown here. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Pause the tutorial and update the code as shown. | ||
+ | |||
+ | |||
+ | |||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | '''if blog_id''' | ||
+ | |||
+ | '''blog = Blog.objects.get(id=blog_id)''' | ||
+ | || When '''id''' matches with''' blog id, get function returns''' the corresponding '''blog object.''' | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | '''else:''' | ||
+ | |||
+ | '''blog = Blog()''' | ||
+ | || In the '''Else statement''', an '''unbound instance''' of the '''Blog''' is created. | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | '''if form.is_valid():''' | ||
+ | |||
+ | '''form.save()''' | ||
+ | |||
+ | '''return get_blogs(request)''' | ||
+ | || When the '''form''' validation is done, the changes are saved. | ||
+ | |||
+ | |||
+ | '''Return statement''' contains our '''view function get_blogs.''' | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | '''get_blogs(request)''' | ||
+ | || The '''view function get_blogs '''is used to get the '''blog objects '''that we have created. | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | '''blog_form = BlogForm(instance=blog)''' | ||
+ | || Here, we create a '''form instance BlogForm.''' | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | '''instance=blog''' | ||
+ | || '''instance equal to blog '''will initialize the values of the '''form fields'''. | ||
+ | |||
+ | These values are provided by the '''blog object'''. | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | '''context = {'form': blog_form, 'blog': blog}''' | ||
+ | || Here, we set the '''context variable''' as "'''form'''" and "'''blog'''". | ||
+ | |- | ||
+ | || [views.py] Highlight | ||
+ | |||
+ | ''''blog': blog''' | ||
+ | || '''blog''' is the '''context variable''' that contains '''Blog objects''' as '''key value.''' | ||
+ | |- | ||
+ | | Press Ctrl+S | ||
+ | | Save the file. | ||
+ | |- | ||
+ | || Switch to templates/add_blog.html file | ||
+ | | Now, switch to '''add_blog.html '''file under '''templates.''' | ||
+ | |- | ||
+ | || [add_blog.html]Type: | ||
+ | |||
+ | |||
+ | <html> | ||
+ | |||
+ | <body> | ||
+ | |||
+ | <form action="/blogs/add_blog/<nowiki>{{ blog.id }}</nowiki>/" method="POST"> | ||
+ | |||
+ | {% csrf_token %} | ||
+ | |||
+ | <nowiki> {{ form }} </nowiki> | ||
+ | |||
+ | <input type="submit" value="Submit" /> | ||
+ | |||
+ | </form> | ||
+ | |||
+ | </body> | ||
+ | |||
+ | </html> | ||
+ | || | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Replace the code as shown here. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |- | ||
+ | || [add_blog.html] Highlight | ||
+ | |||
+ | '''<form action="/blogs/add_blog/<nowiki>{{ blog.id }}</nowiki>/" method="POST">''' | ||
+ | || In '''form''' action, include the reference '''path '''to the existing '''blog object.''' | ||
+ | |- | ||
+ | || [add_blog.html] | ||
+ | |||
+ | Highlight the complete code | ||
+ | || So now we can edit our existing''' blog object''' using '''id.''' | ||
+ | |- | ||
+ | | Press Ctrl+S | ||
+ | | Save the file. | ||
+ | |- | ||
+ | || Switch to blog/urls.py | ||
+ | || Switch to '''urls.py '''file in the '''blog''' directory to include the '''path.''' | ||
+ | |- | ||
+ | || [urls.py] Type | ||
+ | |||
+ | path('add_blog/<int:blog_id>/', views.add_blog, name='edit_blog'), | ||
+ | || Add a new '''URL path''' as shown here. | ||
+ | |- | ||
+ | || [urls.py] Highlight | ||
+ | |||
+ | |||
+ | path('add_blog/'''<int:blog_id>/'''', views.add_blog, name='edit_blog'), | ||
+ | || Here, we have included '''add_blog path''' with '''int blog_id'''. | ||
+ | |||
+ | |||
+ | So that we can edit the existing '''blog object '''using '''blog id.''' | ||
+ | |- | ||
+ | || [urls.py] Highlight | ||
+ | |||
+ | |||
+ | path('add_blog/', views.add_blog, '''name='add_blog''''), | ||
+ | |||
+ | path('add_blog/<int:blog_id>/', views.add_blog, '''name='edit_blog''''), | ||
+ | || The two '''URL paths, "add blog"''' and '''"edit blog"''' are different. | ||
+ | |||
+ | |||
+ | But handled by the same '''view function.''' | ||
+ | |- | ||
+ | | Press Ctrl+S | ||
+ | | Save the file. | ||
+ | |- | ||
+ | || Switch to Terminal | ||
+ | || Let us now edit '''blogs.html ''' | ||
+ | |- | ||
+ | || [Terminal Tab 1] | ||
+ | |||
+ | |||
+ | Type gedit blog/templates/blog/blogs.html & [Enter] | ||
+ | || Switch to the first '''terminal'''. | ||
+ | |||
+ | Type the ''command'' as shown. | ||
+ | |- | ||
+ | || [blogs.html] Type: | ||
+ | |||
+ | |||
+ | <!DOCTYPE html> | ||
+ | |||
+ | <html> | ||
+ | |||
+ | <body> | ||
+ | |||
+ | <nowiki> <h3>Edit Blog: </h3> <nowiki> | ||
+ | |||
+ | {% if blogs %} | ||
+ | |||
+ | <nowiki> <ul> </nowiki> | ||
+ | |||
+ | {% for blog in blogs %} | ||
+ | |||
+ | <nowiki> <li>{{blog.name}}<a href='/blogs/add_blog/{{blog.id}}'> [Edit]</a></li> </nowiki> | ||
+ | |||
+ | {% endfor %} | ||
+ | |||
+ | {% else %} | ||
+ | |||
+ | <nowiki> <p>No Blog articles are available.</p> </nowiki> | ||
+ | |||
+ | <nowiki> </ul> </nowiki> | ||
+ | |||
+ | {% endif %} | ||
+ | |||
+ | </body> | ||
+ | |||
+ | </html> | ||
+ | || | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Update the code as shown here. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |- | ||
+ | || [blogs.html] Highlight | ||
+ | |||
+ | '''<nowiki> <li>{{blog.name}}<a href='/blogs/add_blog/{{blog.id}}'> [Edit]</a></li></nowiki>''' | ||
+ | || Here we have added the link that redirect to edit '''existing blog.''' | ||
+ | |- | ||
+ | || [blogs.html] Highlight | ||
+ | |||
+ | ''' <nowiki> {{ blog.name }} </nowiki>''' | ||
+ | || '''blog.name''' will display the particular '''blog object''' that matches with its '''blog id.''' | ||
+ | |- | ||
+ | || [blogs.html] Highlight | ||
+ | |||
+ | '''<nowiki><p>No Blogs are available.</p></nowiki>''' | ||
+ | || If there is no '''blogs''' available,''' else statement returns "No Blogs are available"'''. | ||
+ | |- | ||
+ | | Press Ctrl+S | ||
+ | | Save the file. | ||
+ | |- | ||
+ | || | ||
+ | || We have now set everything to edit the existing''' Blog''' title. | ||
+ | |- | ||
+ | | Switch to browser | ||
+ | | Now, switch to the '''browser.''' | ||
+ | |- | ||
+ | || [browser] Open a browser and type | ||
+ | |||
+ | |||
+ | http://localhost:8000/blogs/get_blogs/ [Enter] | ||
+ | || In the address bar, type the '''URL''' as shown and press '''Enter.''' | ||
+ | |- | ||
+ | || [browser] | ||
+ | |||
+ | (pointing to the web page) | ||
+ | || Here, we see the '''Blogs''' which we have created earlier in this series with an '''edit option.''' | ||
+ | |||
+ | |||
+ | '''Blog models''' which we have created in this tutorial are also available. | ||
+ | |- | ||
+ | || [browser] | ||
+ | |||
+ | |||
+ | Click '''Edit '''(beside blog name '''MY BLOG''') | ||
+ | || Beside '''blog''' name '''MY BLOG, '''click on '''Edit.''' | ||
+ | |||
+ | |||
+ | It will redirect to the '''edit form''' page. | ||
+ | |- | ||
+ | || [browser] | ||
+ | |||
+ | Type Newly Edited Blog (in Text Box) | ||
+ | || Now, change the '''blog '''name into '''“Newly Edited Blog”.''' | ||
+ | |- | ||
+ | || [browser] | ||
+ | Click '''Submit''' | ||
+ | || Then click on the '''Submit''' button. | ||
+ | |||
+ | We see the '''blog''' name has been changed from '''My Blog''' to '''Newly Edited Blog.''' | ||
+ | |- | ||
+ | || Switch to the terminal. | ||
+ | || This is how we create and edit a '''blog''' using '''Django Form.''' | ||
+ | |||
+ | Switch to the second '''terminal.''' | ||
+ | |- | ||
+ | || Terminal] Press Ctrl+C keys | ||
+ | |||
+ | Type deactivate [Enter] | ||
+ | || Stop the '''server. ''' | ||
+ | |||
+ | And deactivate the '''virtual environment.''' | ||
+ | |- | ||
+ | || Switch to Slide | ||
+ | || With this, we come to the end of this tutorial. | ||
+ | |||
+ | Let us summarize. | ||
+ | |- | ||
+ | || Slide: Summary | ||
+ | || In this tutorial, we have learnt to | ||
+ | |||
+ | * Create a '''Django form''' | ||
+ | * Create '''views '''to handle '''form submission''' | ||
+ | |- | ||
+ | || Slide: Assignment | ||
+ | || As an assignment, | ||
+ | * Create and edit '''Article '''using''' Django Form''' | ||
+ | |||
+ | |- | ||
+ | || Slide: About Spoken Tutorial project | ||
+ | || The video at the following link summarises the Spoken Tutorial project. | ||
+ | |||
+ | Please download and watch it. | ||
+ | |- | ||
+ | || Slide: Spoken Tutorial workshops | ||
+ | || The '''Spoken Tutorial Project''' team conducts workshops and gives certificates. | ||
+ | |||
+ | For more details, please write to us. | ||
+ | |- | ||
+ | || Slide: Forum for specific questions: | ||
+ | | | Please post your timed queries in this Forum. | ||
+ | |- | ||
+ | || Slide: FOSSEE to answer questions | ||
+ | | | Please post your general or technical questions in this Forum. | ||
+ | |- | ||
+ | || Slide: Acknowledgement | ||
+ | || Spoken Tutorial Project is funded by NMEICT, MHRD, Government of India. | ||
+ | |||
+ | More information on this mission is available at this link. | ||
+ | |- | ||
+ | || Slide: Thanks Slide | ||
+ | || This script has been contributed by Thiagarajar College of Engineering and the FOSSEE Project, IIT Bombay. | ||
+ | |||
+ | The video has been recorded by Praveen from Spoken Tutorial Project, IIT Bombay. | ||
+ | |||
+ | Thanks for watching. | ||
+ | |- | ||
+ | |} |
Latest revision as of 08:42, 10 October 2019
Django/C2/Creating-Forms-in-Django/English
Title of script: Creating Forms in Django
Keywords: Video tutorial, Django views, Django Forms
Visual cue | Narration |
Slide: Creating Forms in Django | Hello and Welcome to the spoken tutorial on “Creating Forms in Django” |
Slide: Learning Objectives | In this tutorial, we will learn to:
|
Slide: System Requirements | To record this tutorial, I am using
|
Slide: Prerequisites | To follow this tutorial, you need to know
|
Slide: Forms |
|
Open a Terminal window
|
Let us open the terminal by pressing Ctrl, Alt and T keys simultaneously on the keyboard. |
[Terminal]
cd my-django [Enter] |
Now using the cd command, go to the folder my hyphen django which we created earlier. |
[Terminal]
Type source myapp_env/bin/activate and press Enter |
Activate the virtual environment myapp underscore env |
[Terminal] cd mysite [Enter] | Then go to the mysite folder using the cd command. |
Here onwards, please remember to press the Enter key after typing each command. | |
[Terminal]
Type gedit blog/forms.py & [Enter] |
Let us now create a form in Django using models.
To do so, create a file forms dot py in the blog directory. Type the command as shown. |
[forms.py]Type:
from blog.models import Blog, Article from django import forms
class Meta: model = Blog fields = ['name'] class ArticleForm(forms.ModelForm): class Meta: model = Article fields = ['title', 'body', 'draft'] |
We are now in forms.py file.
Type the code as shown here. |
[forms.py] Highlight
class ArticleForm(forms.ModelForm): |
Django provides a class ModelForm to create a Form from a Model.
|
[forms.py] Highlight
class Meta: |
To provide data to the Form class, we are using an inner class Meta. |
[forms.py] Highlight
model = Blog |
We are assigning the Blog model which is used to generate Form. |
[forms.py] Highlight
fields = ['name'] |
In Meta class, Fields attribute is used to select the fields to use in the form. |
[forms.py] Highlight
class ArticleForm(forms.ModelForm): class Meta: model = Article fields = ['title', 'body', 'draft'] |
Similarly we have defined an inner class named Meta with fields for the Article Form. |
[forms.py] Highlight
from blog.models import Blog, Article |
Here, we have imported our models, Blog and Article. |
[forms.py] Highlight
from django import forms |
To create django forms, we need to import forms from Django. |
[forms.py] Highlight the complete code | Now, we have defined Django form using models. |
Press Ctrl+S | Save the file. |
Switch to Terminal | Switch back to the terminal to create a template file to call our Django form. |
[Terminal]
Type gedit blog/templates/add_blog.html & [Enter] |
Create an HTML file add underscore blog in templates directory.
Type the command as shown. |
[add_blog.html]Type:
<body> <form action="" method="POST"> {% csrf_token %} {{ form }} <input type="submit" value="Add Blog" /> </form> </body> </html> |
We are now in add_blog.html,
|
[add_blog.html] Highlight
{% csrf_token %} |
CSRF - Cross Site Request Forgery Protection
We have to use the csrf_token tag in a template which uses the form POST request. Django provides built-in CSRF protection to protect the server from malicious websites. |
[add_blog.html] Highlight
{{ form }} |
Here we have included our context variable to display our Django Form. |
[add_blog.html] Highlight
<input type="submit" value="Add Blog" /> |
Here, we have created a button to submit the form. |
[add_blog.html] Highlight the complete code | We have created a HTML template to use a form passed through context. |
Press Ctrl+S | Save the file. |
Switch to Terminal | Switch to the terminal. |
[Terminal]
Type gedit blog/views.py & [Enter] |
Open the file views.py to use this template.
|
[views.py]:
from django.http import HttpResponse from .models import Blog, Article from blog.forms import BlogForm, ArticleForm
return HttpResponse("Hello World")
blogs = Blog.objects.all() context = {'blogs': blogs} return render(request, 'blog/blogs.html', context)
if request.method == 'POST': form = BlogForm(request.POST) if form.is_valid(): form.save() return HttpResponse("Blog created") else: context = {'form': form} return render(request, 'add_blog.html', context) context = {'form': BlogForm()} return render(request, 'add_blog.html', context) |
We are now in views.py file.
|
[views.py] Highlight
if request.method == 'POST': |
If this is a POST request, we need to process the form data. |
[views.py] Highlight
|
We have created an instance of the BlogForm class object using the data from the POST request.
|
[views.py] Highlight
from blog.forms import BlogForm |
We have imported the BlogForm from our blog’s form. |
[views.py] Highlight
|
Next, is_valid() method is used to check whether the entered data is valid or not.
If the data is valid then is_valid() function returns True. Otherwise it returns False. |
[views.py] Highlight
else part of def add_blog(request) |
In the Else statement, when the data is empty or invalid, it will return the form with errors. |
[views.py] Highlight
form.save() |
When the form data is valid, we save a new Blog object from the form. |
[views.py] Highlight
return HttpResponse("Blog created") |
After successful addition of the blog, let’s return something.
|
[views.py] Highlight
context = {'form': BlogForm()} |
If the request is GET_ request, then this will be executed.
An empty form instance of BlogForm is created. Then, the form instance is added to context. This context will be provided to the HTML template while rendering. |
[views.py] Highlight
form = BlogForm(request.POST) |
This is what will happen when a form is submitted using a POST request.
A form instance is created and data from the request is populated with it. This is called “binding data to the form”. It is now a bound form |
[views.py] Highlight
from django.shortcuts import render from django.http import HttpResponse from .models import Blog, Article |
Here we can see that, the necessary modules have already been imported. |
[views.py] Highlight
def add_blog(request) section |
We have added a function in our views to add Blog with use of Form data. |
Press Ctrl+S | Save the file. |
Switch to Terminal | Switch to the Terminal. |
[Terminal]
Type gedit blog/urls.py & [Enter] |
Now, we will insert the path in the URL configuration.
Type the command as shown. |
[urls.py]
Type path('add_blog/', views.add_blog, name='add_blog'), |
We are now in urls.py file in blog app.
Insert the new path as shown here. |
[urls.py] | We have added the path in blog app Urls.
And there are no changes in the root Urls. |
Press Ctrl+S | Save the file. |
Switch to Terminal | Switch to the Terminal. |
[Terminal]
Press CTRL+SHIFT+T |
For our convenience, let us run the Django server in a separate terminal.
Press Shift, Ctrl and T keys simultaneously. |
[Terminal Tab 2]Type: cd ..
Type source myapp_env/bin/activate and press Enter |
In the new terminal tab, go to my-django directory using the cd command.
Activate the virtual environment. |
[Terminal tab 2] type cd mysite
Type python manage.py runserver [Enter] |
Now go to the mysite folder using cd command
Start the server. |
Open a browser and type | Now we will call the view function add underscore blog.
Open the web browser, and type the URL as shown and press Enter. |
[browser]
Point to the form |
Here, we see a form with a labelled text Name.
Along with the input textbox and a Submit button. |
[browser] (Cursor at text box)
press space key |
Let us first try with some invalid data.
In the textbox enter spaces by pressing Space key multiple times. |
[browser] Click Add Blog | Click on the Add Blog button to save. |
[browser]
(pointing to the error message) |
Here, we see an error message “This field is required.”
So the blog is not created with invalid data. |
[gedit] blog/views.py highlight
if form.is_valid():... else: context = {'form': form} return render(request, 'add_blog.html', context) |
In this way we can handle the invalid data.
|
[browser] (Cursor at text box)
Type MY BLOG |
Now, let us type MY BLOG in the text box. |
[browser]
Click Add Blog |
Click on the Add Blog button to save the Blog. |
[browser]
(pointing to the web page) |
Now, after submission, we get the response as Blog created. |
Switch to views.py file from browser | Let us now move to our views.py file to edit the existing Blog. |
[views.py]Type:
if blog_id: blog = Blog.objects.get(id=blog_id) else: blog = Blog() if request.method == 'POST': form = BlogForm(request.POST, instance=blog) if form.is_valid(): form.save() return get_blogs(request) else: context = {'form': form} return render(request, 'add_blog.html', context) blog_form = BlogForm(instance=blog) context = {'form': blog_form, 'blog': blog} return render(request, 'add_blog.html', context) |
Modify the function add_blog in the views.py file as shown here.
|
[views.py] Highlight
if blog_id blog = Blog.objects.get(id=blog_id) |
When id matches with blog id, get function returns the corresponding blog object. |
[views.py] Highlight
else: blog = Blog() |
In the Else statement, an unbound instance of the Blog is created. |
[views.py] Highlight
if form.is_valid(): form.save() return get_blogs(request) |
When the form validation is done, the changes are saved.
|
[views.py] Highlight
get_blogs(request) |
The view function get_blogs is used to get the blog objects that we have created. |
[views.py] Highlight
blog_form = BlogForm(instance=blog) |
Here, we create a form instance BlogForm. |
[views.py] Highlight
instance=blog |
instance equal to blog will initialize the values of the form fields.
These values are provided by the blog object. |
[views.py] Highlight
context = {'form': blog_form, 'blog': blog} |
Here, we set the context variable as "form" and "blog". |
[views.py] Highlight
'blog': blog |
blog is the context variable that contains Blog objects as key value. |
Press Ctrl+S | Save the file. |
Switch to templates/add_blog.html file | Now, switch to add_blog.html file under templates. |
[add_blog.html]Type:
<body> <form action="/blogs/add_blog/{{ blog.id }}/" method="POST"> {% csrf_token %} {{ form }} <input type="submit" value="Submit" /> </form> </body> </html> |
|
[add_blog.html] Highlight
<form action="/blogs/add_blog/{{ blog.id }}/" method="POST"> |
In form action, include the reference path to the existing blog object. |
[add_blog.html]
Highlight the complete code |
So now we can edit our existing blog object using id. |
Press Ctrl+S | Save the file. |
Switch to blog/urls.py | Switch to urls.py file in the blog directory to include the path. |
[urls.py] Type
path('add_blog/<int:blog_id>/', views.add_blog, name='edit_blog'), |
Add a new URL path as shown here. |
[urls.py] Highlight
|
Here, we have included add_blog path with int blog_id.
|
[urls.py] Highlight
path('add_blog/<int:blog_id>/', views.add_blog, name='edit_blog'), |
The two URL paths, "add blog" and "edit blog" are different.
|
Press Ctrl+S | Save the file. |
Switch to Terminal | Let us now edit blogs.html |
[Terminal Tab 1]
|
Switch to the first terminal.
Type the command as shown. |
[blogs.html] Type:
<html> <body> <h3>Edit Blog: </h3> <nowiki> {% if blogs %} <nowiki> <ul> {% for blog in blogs %} <li>{{blog.name}}<a href='/blogs/add_blog/{{blog.id}}'> [Edit]</a></li> {% endfor %} {% else %} <p>No Blog articles are available.</p> </ul> {% endif %} </body> </html> |
Update the code as shown here.
|
[blogs.html] Highlight
<li>{{blog.name}}<a href='/blogs/add_blog/{{blog.id}}'> [Edit]</a></li> |
Here we have added the link that redirect to edit existing blog. |
[blogs.html] Highlight
{{ blog.name }} |
blog.name will display the particular blog object that matches with its blog id. |
[blogs.html] Highlight
<p>No Blogs are available.</p> |
If there is no blogs available, else statement returns "No Blogs are available". |
Press Ctrl+S | Save the file. |
We have now set everything to edit the existing Blog title. | |
Switch to browser | Now, switch to the browser. |
[browser] Open a browser and type | In the address bar, type the URL as shown and press Enter. |
[browser]
(pointing to the web page) |
Here, we see the Blogs which we have created earlier in this series with an edit option.
|
[browser]
|
Beside blog name MY BLOG, click on Edit.
|
[browser]
Type Newly Edited Blog (in Text Box) |
Now, change the blog name into “Newly Edited Blog”. |
[browser]
Click Submit |
Then click on the Submit button.
We see the blog name has been changed from My Blog to Newly Edited Blog. |
Switch to the terminal. | This is how we create and edit a blog using Django Form.
Switch to the second terminal. |
Terminal] Press Ctrl+C keys
Type deactivate [Enter] |
Stop the server.
And deactivate the virtual environment. |
Switch to Slide | With this, we come to the end of this tutorial.
Let us summarize. |
Slide: Summary | In this tutorial, we have learnt to
|
Slide: Assignment | As an assignment,
|
Slide: About Spoken Tutorial project | The video at the following link summarises the Spoken Tutorial project.
Please download and watch it. |
Slide: Spoken Tutorial workshops | The Spoken Tutorial Project team conducts workshops and gives certificates.
For more details, please write to us. |
Slide: Forum for specific questions: | Please post your timed queries in this Forum. |
Slide: FOSSEE to answer questions | Please post your general or technical questions in this Forum. |
Slide: Acknowledgement | Spoken Tutorial Project is funded by NMEICT, MHRD, Government of India.
More information on this mission is available at this link. |
Slide: Thanks Slide | This script has been contributed by Thiagarajar College of Engineering and the FOSSEE Project, IIT Bombay.
The video has been recorded by Praveen from Spoken Tutorial Project, IIT Bombay. Thanks for watching. |