Basic Crud in Django 1192935516587314 4
Basic Crud in Django 1192935516587314 4
by Mike Cantelon
Setting Up a Project
1. 2. 3. 4. 5. 6. 7. 8.
Change to the directory in which your project should be created Issue the command django-admin.py startproject linkdump This command will have created a directory, with the specied project name (in this case linkdump), containing base les for the project Change to this directory Issue the command python manage.py runserver to start the development server (http://127.0.0.1:8000) If your project is to use a new, rather than existing, database then create it (unless using sqlite, which be automatically created) Edit settings.py to congure access to your database Issue the command python manage.py syncdb to build database tables needed by the administration interface (useful later). Follow the prompts.
Creating an Application
1. 2. As a simple demonstration, well create an application to submit links to To create the applications directory and base les, we issue the command python manage.py startapp linktracker (linktracker being the name of our application) Next, we edit linktracker/models.py to dene our model
class Link (models.Model): link_description = models.CharField(maxlength=200) link_url = models.CharField(maxlength=200)
3.
4. 5.
To add our app to the project, we edit the projects settings.py to add our app (linkdump.linktracker) to the INSTALLED_APPS list in settings.py To update the database, automatically creating the necessary tables, we issue the command python manage.py syncdb
Activating Administration
1. 2. 3. 4. 5. 6. Add django.contrib.admin to the INSTALLED_APPS list in settings.py Issue the command python manage.py syncdb Edit urls.py to enable admin (the next slide will talk more about this les functionality) Issue the command python manage.py runserver You can verify that admin is running by browsing http://127.0.0.1:8000/admin Edit linktracker/models.py to turn on admin for links: class Link(models.Model): # ... class Admin: pass Edit linktrackers/models.py to enable default (naming) column for links def __str__(self): return self.link_description
7.
Designing URLs
Now that we can enter data, adding a way for user to see this data would be useful To present data we need to write a view which is mapped to a URL pattern Editing urls.py allows URL patterns to be dened using regular expressions Add the below link to your urls.py le: (r^links/$, linkdump.linktracker.views.list) The above line will, if someone browses /links/ on our site, try to display the results of the list view of the links application of the linkdump project... we have not yet created a list view, however, so we just get an error!
Enabling Templating
1. 2. 3. Views usually incorporate HTML templates so presentation is separated from logic To enable templating, create a directory called template in which to store your templates then edit settings.py and add template to TEMPLATE_DIRS Edit linktracker/views.py to create a list view for links that uses templating
from linkdump.linktracker.models import Link from django.template import Context, loader from django.shortcuts import render_to_response def list(request): link_list = Link.objects.all() return render_to_response( links/list.html, {link_list: link_list} )
Creating A Template
1. 2. Well create a template to crudely display link items Edit template/links/list.html:
{% if link_list %} <ul> {% for link in link_list %} <li><a href={{ link.link_url }}> {{link.link_description}}</a></li> {% endfor %} </ul> {% else %} <p>No links found.</p> {% endif %}
3.
Pagination (1 of 3)
Use the admin interface to add a bunch of links then reload the /links/ URL An unlimited list is a problem so we need to add pagination We will have to add pagination support in three places: our URL patterns (urls.py), our list view (linktracker/views.py), and our template (template/links/list.html To add a URL pattern supporting pagination, add the below line to urls.py:
(r^links/(?P<page>\d+), linkdump.linktracker.views.list)
Pagination (2 of 3)
To add pagination support to linktracker/views.py, rst add the following line near the start:
from django.core.paginator import ObjectPaginator, InvalidPage
Pagination (3 of 3)
Last, but not least, youll want to change your template/links/ list.html HTML template to support pagination... add the following lines before the line containing else:
{% if has_previous %} <a href=/https/www.scribd.com/links/{{ previous_page }}>Previous</a> {% if has_next %} | {% endif %} {% endif %} {% if has_next %} <a href=/https/www.scribd.com/links/{{ next_page }}>Next</a> {% endif %}
Also in views.py, add a line in the list view so the passed message is included in the list of parameters relayed to the list.html template:
message: message,
Now that were preparing to add CRUD functionality, we need to update our list HTML template as shown below:
{% if message %} <b>{{ message }}</b> <p> {% endif %} {% if link_list %} <table> {% for link in link_list %} <tr bgcolor='{% cycle FFFFFF,EEEEEE as rowcolor %}'> <td><a href='{{ link.link_url }}'>{{ link.link_description }}</a></td> <td><a href='/links/edit/{{ link.id }}'>Edit</a></td> <td><a href='/links/delete/{{ link.id }}'>Delete</a></td> </tr> {% endfor %} </table> <p> {% if has_previous %} <a href='/links/{{ previous_page }}'>Previous</a> {% if has_next %}|{% endif %} {% endif %} {% if has_next %} <a href='/links/{{ next_page }}'>Next</a> {% endif %} {% else %} <p>No links found.</p> {% endif %} <p> <a href='/links/new'>Add Link</a>
Creating Data (1 of 2)
Allowing users to submit data requires rst displaying an HTML form then adding the submitted data To start, add a URL for form display to urls.py:
(r^links/new, linkdump.linktracker.views.new)
Then, to display an HTML add form in linktracker/views.py, add the following block of code:
def new(request): return render_to_reponse( links/form.html, {action: add, button: Add} )
Creating Data (2 of 2)
Next, we add the form HTML template (which, as written below, can be used for adding or editing, as well see later):
<form action=/links/{{ action }}/ method=post> Description: <input name=link_description value={{ link.link_description|escape}}><br /> URL: <input name=link_url value={{ link.link_url|escape }}><br /> <input type=submit value={{ button }}> </form>
Finally, we add logic to linktracker/views.py to add the submitted data then return to the list view, passing a message:
def add(request): link_description = request.POST[link_description] link_url = request.POST[link_url] link = Link( link_description = link_description, link_url = link_url ) link.save() return list(request, message=Link added!)
Updating Data (1 of 2)
Allowing users to upate data requires rst displaying an HTML form showing current data then, upon submission, doing the actual update To start, add a URL for form display to urls.py:
(r^links/edit/(?P<id>\d+), linkdump.linktracker.views.edit)
Then, to display an HTML edit form in linktracker/views.py, add the following block of code:
def edit(request, id): link = Link.objects.get(id=id) return render_to_reponse( links/form.html, {action: update/ + id, button: Update} )
NOTE: As the HTML form we added earlier can be used to edit, were reusing it in the above code
Updating Data (2 of 2)
To deal with submitted updates, we add another URL to urls.py:
(r^links/update/(?P<id>\d+), linkdump.linktracker.views.update)
Finally, we add logic to linktracker/views.py to add the submitted data then return to the list view, passing a message:
def update(request, id): link = Link.objects.get(id=id) link.link_description = request.POST[link_description] link.link_url = request.POST[link_url] link.save() return list(request, message=Link updated!)
Deleting Data
Allowing users to delete data requires rst displaying an HTML form showing current data then, upon submission, doing the actual update To support deletion, add a new URL pattern to urls.py:
(r'^links/delete/(?P<id>\d+)', 'diglic.links.views.delete')
Then, to display an HTML edit form in linktracker/views.py, add the following block of code:
def delete(request, id): Link.objects.get(id=id).delete() return list(request, message=Link deleted!)