1 of 37

The Django Admin Site

  • Web-based interface, limited to trusted site administrators, that enables the adding, editing, and deletion of site content.
  • authenticate users, display and handle forms, validate input, and so on.
  • It’s boring and it’s repetitive.

Prof.Latha

1

6/27/2024

2 of 37

django.contrib Packages

  • Django’s automatic admin is part of a larger suite of Django functionality called
    • django. contrib —part of the Django codebase that contains various useful add-ons to the core framework.

  • The admin site is the first part of django.contrib called django.contrib.admin.
  • Other available features in django.contrib include a
    • user-authentication system (django.contrib.auth),
    • support for anonymous sessions (django. contrib.sessions), and
    • even a system for user comments (django.contrib.comments).

Prof.Latha

2

6/27/2024

3 of 37

Activating the Admin Interface

  • Django admin site is entirely optional.
  • Few steps are needed to activate it in project.
  • First, make a few changes to your settings file:
      • Add 'django.contrib.admin' to the INSTALLED_APPS setting.
      • The Django admin site requires these three packages. Make sure INSTALLED_APPS contains
        • 'django.contrib.auth',
        • 'django.contrib. contenttypes', and
        • 'django.contrib.sessions'.
      • Make sure MIDDLEWARE_CLASSES contains
        • 'django.middleware.common.CommonMiddleware',
        • 'django.contrib.sessions.middleware.SessionMiddleware', and
        • 'django.contrib. auth.middleware.AuthenticationMiddleware'.

Prof.Latha

3

6/27/2024

4 of 37

Activating the Admin Interface

  • Second, run python manage.py syncdb.
    • This step will install the extra database tables that the admin interface uses.
    • The first time you run syncdb with 'django.contrib.auth' in INSTALLED_APPS, you’ll be asked about creating a superuser.
    • If you don’t do this, run python manage.py createsuperuser separately to create an admin user account;
    • otherwise you won’t be able to log in to the admin site.
    • the python manage.py createsuperuser command is available only if 'django.contrib.auth' is in your INSTALLED_ APPS.)

Prof.Latha

4

6/27/2024

5 of 37

Activating the Admin Interface

  • Third, add the admin site to your URLconf (in urls.py, remember). By default, the urls.py generated by django-admin.py startproject contains commented-out code for the Django admin, and all you have to do is uncomment it. For the record, here are the bits you need to make sure are in there:

Prof.Latha

5

6/27/2024

# Include these import statements

from django.contrib import admin admin.autodiscover()

 

# And include this URLpattern...

urlpatterns = patterns('',

# ...

(r'^admin/', include(admin.site.urls)), #

)

6 of 37

Using the Admin Site

  • Log in with the username and password you set up when you added your superuser
  • If unable to log in,
    • create a superuser—by running python manage.py createsuperuser command

Prof.Latha

6

6/27/2024

  • Once logged in, admin home page is displayed which lists all the available types of data that can be edited on the admin site.

  • At this point, it includes only Groups and Users, which are the two default admin-editable models.

7 of 37

User edit form

  • Each type of data in the Django admin site has a change list and an edit form. Change lists show you all the available objects in the database, and edit forms let you add, change, or delete particular records in your database.
  • Click the Change link in the Users row to load the change-list page for users
  • This page displays all users in the database

SELECT * FROM auth_user

Prof.Latha

7

6/27/2024

8 of 37

The user edit form

Prof.Latha

8

6/27/2024

9 of 37

Adding Your Models to the Admin Site

Prof.Latha

9

6/27/2024

from django.contrib import admin

from mysite.student.models import Student

#or from .models import Book

 

admin.site.register(Book)

  • This code tells the Django admin site to offer an interface for each of these models.
  • go to your admin home page in your Web browser (http://127.0. 0.1:8000/admin/). And observe Student/book section with links add and change records

10 of 37

How the Admin Site Works

Prof.Latha

10

6/27/2024

  • When Django loads URLconf from urls.py at server startup, it executes the admin. autodiscover() statement that is added as part of activating the admin.
  • This function iterates over your INSTALLED_APPS setting and looks for a file called admin.py in each installed app. If an admin.py exists in a given app, it executes the code in that file.
  • In the admin.py in our student app, each call to admin.site.register() simply registers the given model with the admin.
  • The admin site will display an edit/change interface for only models that have been explicitly registered.
  • The app django.contrib.auth includes its own admin.py, which is why Users and Groups showed up automatically in the admin.
  • Other django.contrib apps, such as django.contrib. redirects, also add themselves to the admin, as do many third-party Django applications you might download from the Web.
  • Beyond that, the Django admin site is just a Django application, with its own models, templates, views, and URLpatterns. You add it to your application by hooking it into your URLconf, just as you hook in your own views. You can inspect its templates, views, and URL- patterns by poking around in django/contrib/admin in your copy of the Django  

11 of 37

Making Fields Optional

class Author(models.Model):

first_name = models.CharField(max_length=30)

last_name = models.CharField(max_length=40)

email = models.EmailField

By default, all fields have blank=False, which means blank values are not allowed.

class Author(models.Model):

first_name = models.CharField(max_length=30)

last_name = models.CharField(max_length=40)

email = models.EmailField(blank=True)

Prof.Latha

11

6/27/2024

12 of 37

Making Date and Numeric Fields Optional

class Book(models.Model):

title = models.CharField(max_length=100)

authors = models.ManyToManyField(Author)

publisher = models.ForeignKey(Publisher)

publication_date = models.DateField(blank=True, null=True)

Prof.Latha

12

6/27/2024

13 of 37

Customizing Field Labels

class Author(models.Model):

first_name = models.CharField(max_length=30)

last_name = models.CharField(max_length=40)

email = models.EmailField(blank=True, verbose_name='e-mail')

  • We can pass the verbose_name as a positional argument, for a slightly more compact syntax.

email = models.EmailField('e-mail', blank=True)

    • This won’t work with ManyToMany Field or ForeignKey fields, though, because they require the first argument to be a model class. In those cases, specifying verbose_name explicitly is the way to go.

Prof.Latha

13

6/27/2024

14 of 37

Custom ModelAdmin Classes

  • The changes made —> blank=True, null=True, and verbose_name—are model-level changes, not admin-level changes.
  • Customizing Change Lists

class Author(models.Model):

first_name = models.CharField(max_length=30)

last_name = models.CharField(max_length=40)

email = models.EmailField(blank=True,

verbose_name='e-mail')

 

def unicode (self):

return u'%s %s' % (self.first_name, self.last_name)

Prof.Latha

14

6/27/2024

class AuthorAdmin(admin.ModelAdmin):

list_display = ('first_name', 'last_name')

 

admin.site.register(Author, AuthorAdmin)

15 of 37

Add a simple search bar

  • add following code to AuthorAdmin class in admin.py. Search is case sensitive

search_fields = ('first_name', 'last_name')

Prof.Latha

15

6/27/2024

16 of 37

Filter content based on date

class BookAdmin(admin.ModelAdmin):

list_display = ('title', 'publisher', 'publication_date')

list_filter = ('publication_date',)

 

admin.site.register(Publisher)

admin.site.register(Author, AuthorAdmin)

admin.site.register(Book, BookAdmin)

Prof.Latha

16

6/27/2024

17 of 37

Filter and order data based on publication date

list_filter = ('publication_date',)

# Ascending order

ordering = ('publication_date',)

Or

list_filter = ('publication_date',)

# Ascending order

ordering = ('publication_date',)

date_hierarchy = 'publication_date'

Prof.Latha

17

6/27/2024

18 of 37

Customizing Edit Forms

For example, in our book database, we could prevent the publication_date field from being editable:

 

class BookAdmin(admin.ModelAdmin):

list_display = ('title', 'publisher', 'publication_date')

list_filter = ('publication_date',)

date_hierarchy = 'publication_date'

ordering = ('-publication_date',)

fields = ('title', 'authors', 'publisher',)

 

#make sure  publication_date field should be set to null in model.py

publication_date = models.DateField(blank=True, null=True)

Prof.Latha

18

6/27/2024

19 of 37

Prof.Latha

19

6/27/2024

20 of 37

Forms-Getting Data from the Request Object

from django.http import HttpResponse

def hello(request):

return HttpResponse("Hello world“)

HttpRequest objects contain several pieces of information about the currently requested URL,

Prof.Latha

20

6/27/2024

21 of 37

Always use the attributes/methods outlined in Table 7-1 instead of hard-coding URLs in your views. # BAD!

def current_url_view_bad(request):

return HttpResponse("Welcome to the page at /current/")

 

# GOOD

def current_url_view_good(request):

return HttpResponse("Welcome to the page at %s" % request.path)

 

Prof.Latha

21

6/27/2024

22 of 37

Other Information About the Request

  • request.META – a Python dictionary containing all available HTTP headers for the given request—including the user’s IP address and user agent
  • Commonly use headers
    • HTTP_REFERER: The referring URL, if any. (Note the misspelling of REFERER.)
    • HTTP_USER_AGENT: The user-agent string (if any) of the user’s browser. This looks some- thing like the following:

"Mozilla 5.0 (X11; U; Linux i686) Gecko/20080829 Firefox/2.0.0.17"

    • REMOTE_ADDR: The IP address of the client—for instance, "12.345.67.89". (If the request has passed through any proxies, then this might be a comma-separated list of IP addresses, such as "12.345.67.89,23.456.78.90".)

Prof.Latha

22

6/27/2024

23 of 37

request.META

  • basic Python dictionary, hence you’ll get a KeyError exception if you try to access a key that doesn’t exist.
  • HTTP headers are external data— they’re submitted by users’ browsers—they shouldn’t be trusted.
  • always design application to fail gracefully if a particular header is empty or doesn’t exist

# BAD!

def ua_display_bad(request):

ua = request.META['HTTP_USER_AGENT']

# Might raise KeyError!

return HttpResponse("Your browser is %s" % ua)

Prof.Latha

23

6/27/2024

 # GOOD (VERSION 1)

def ua_display_good1(request):

try:

ua = request.META['HTTP_USER_AGENT']

except KeyError:

ua = 'unknown'

return HttpResponse("Your browser is %s" % ua)

# GOOD (VERSION 2)

def ua_display_good2(request):

ua = request.META.get('HTTP_USER_AGENT', 'unknown')

return HttpResponse("Your browser is %s" % ua)

24 of 37

Information About Submitted Data

  • HttpRequest objects have two attributes that contain user-submitted information:
    • request.GET and
    • request.POST.
  • Both of these are dictionary-like objects that give you access to GET and POST data.
    • POST data generally is submitted from an HTML <form>,
    • while GET data can come from a <form> or the query string in the page’s URL.

Prof.Latha

24

6/27/2024

25 of 37

A Simple Form-Handling Example

  • Generally, there are two parts to developing a form:
    • the HTML user interface and
    • the back-end view code that processes the submitted data.
  • The first part is easy; let’s just set up a view that displays a search form in books/views.py :

from django.shortcuts import render_to_response

def search_form(request):

return render_to_response('search_form.html')

Prof.Latha

25

6/27/2024

The accompanying template, search_form.html, could look like this:

<html>

<head>

<title>Search</title>

</head>

<body>

<form action="/search/" method="get">

<input type="text" name="q">

<input type="submit" value="Search">

</form>

</body>

</html>

26 of 37

A Simple Form-Handling Example

The URLpattern in urls.py could look like this:

from mysite.books import views

 urlpatterns = patterns('', (r'^search-form/$', views.search_form),

)

Run server & observe the output says 404 error when you give /search

Fix the error with following code

urlpatterns = patterns('', (r'^search-form/$', views.search_form),

(r'^search/$', views.search),

)

Prof.Latha

26

6/27/2024

# views.py

 def search(request):

if 'q' in request.GET:

message = 'You searched for: %r' % request.GET['q']

else:

message = 'You submitted an empty form.'

return HttpResponse(message)

here’s what happens:

The HTML <form> defines a variable q. When it’s submitted, the value of q is sent via GET (method="get") to the URL /search/.

The Django view that handles the URL /search/ (search()) has access to the q value in request.GET.

27 of 37

from django.http import HttpResponse

from django.shortcuts import render_to_response

from mysite.books.models import Book

 

def search(request):

if 'q' in request.GET and request.GET['q']:

q = request.GET['q']

books = Book.objects.filter(title icontains=q)

return render_to_response('search_results.html', {'books': books, 'query': q})

else:

return HttpResponse('Please submit a search term.')

Prof.Latha

27

6/27/2024

<p>You searched for: <strong>{{ query }} </strong></p>

 

{% if books %}

<p>Found {{ books|length }} book{{ books|pluralize }}.</p>

<ul>

{% for book in books %}

<li>{{ book.title }}</li>

{% endfor %}

</ul>

{% else %}

<p>No books matched your search criteria.</p>

{% endif %}

28 of 37

Improving Our Simple Form-Handling Example

from django.http import HttpResponse

from django.shortcuts import render_to_response

from mysite.books.models import Book

 

def search_form(request):

return render_to_response('search_form.html')

 

def search(request):

if 'q' in request.GET and request.GET['q']:

q = request.GET['q']

books = Book.objects.filter(title icontains=q)

return render_to_response('search_results.html',

{'books': books, 'query': q})

else:

return render_to_response('search_form.html', {'error': True})

Prof.Latha

28

6/27/2024

29 of 37

Prof.Latha

29

6/27/2024

30 of 37

Prof.Latha

30

6/27/2024

31 of 37

Prof.Latha

31

6/27/2024

32 of 37

Prof.Latha

32

6/27/2024

33 of 37

Prof.Latha

33

6/27/2024

34 of 37

Prof.Latha

34

6/27/2024

35 of 37

Prof.Latha

35

6/27/2024

36 of 37

Prof.Latha

36

6/27/2024

37 of 37

Prof.Latha

37

6/27/2024

Thank You