Sunday, 6 September 2015

Day 13 - forms

A Simple Form-Handling Example

Continuing this book’s ongoing example of books, authors and publishers, let’s create a simple view that lets users search our book database by title.
Generally, there are two parts to developing a form: the HTML user interface and the backend view code that processes the submitted data. The first part is easy; let’s just set up a view that displays a search form:
from django.shortcuts import render

def search_form(request):
    return render(request, 'search_form.html')
As we learned in Chapter 3, this view can live anywhere on your Python path. For sake of argument, put it inbooks/views.py.
render (request, name of template html in '')
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>
The URLpattern in urls.py could look like this:
from mysite.books import views

urlpatterns = patterns('',
    # ...
    url(r'^search-form/$', views.search_form),
    # ...
)
(Note that we’re importing the views module directly, instead of something likefrom mysite.views import search_form, because the former is less verbose. We’ll cover this importing approach in more detail in Chapter 8.)
Now, if you run the runserver and visit http://127.0.0.1:8000/search-form/, you’ll see the search interface. Simple enough.
Try submitting the form, though, and you’ll get a Django 404 error. The form points to the URL /search/, which hasn’t yet been implemented. Let’s fix that with a second view function:
# urls.py

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

# 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)
For the moment, this merely displays the user’s search term, so we can make sure the data is being submitted to Django properly, and so you can get a feel for how the search term flows through the system. In short:
  1. 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/.
  2. The Django view that handles the URL /search/ (search()) has access to the q value in request.GET.

Tuesday, 25 August 2015

Day 12 - Admin interface beginning

First, make a few changes to your settings file:
  1. Add 'django.contrib.admin' to the INSTALLED_APPS setting. (The order of INSTALLED_APPS doesn’t matter, but we like to keep things alphabetical so it’s easy for a human to read.)
  2. Make sure INSTALLED_APPS contains 'django.contrib.auth''django.contrib.contenttypes','django.contrib.messages' and 'django.contrib.sessions'. The Django admin site requires these three packages. (If you’re following along with our ongoing mysite project, note that we commented out these fourINSTALLED_APPS entries in Chapter 5. Uncomment them now.)
  3. Make sure MIDDLEWARE_CLASSES contains 'django.middleware.common.CommonMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.contrib.sessions.middleware.SessionMiddleware' and'django.contrib.auth.middleware.AuthenticationMiddleware'. (Again, if you’re following along, note that we commented them out in Chapter 5, so uncomment them.)


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, you’ll need to 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. (Potential gotcha: thepython manage.py createsuperuser command is only available if 'django.contrib.auth' is in yourINSTALLED_APPS.)


Third, add the admin site to your URLconf (in urls.py, remember). By default, the urls.py generated bydjango-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:
# Include these import statements...
from django.contrib import admin
admin.autodiscover()

# And include this URLpattern...
urlpatterns = patterns('',
    # ...
    (r'^admin/', include(admin.site.urls)),
    # ...
)



Monday, 24 August 2015

Day 11 - Data Base setting

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': '',                      # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}
Here’s a rundown of each setting.
  • ENGINE tells Django which database engine to use. If you’re using a database with Django, ENGINE must be set to one of the strings shown in Table 5-1.
    Table 5-1. Database Engine Settings
    Setting
    Database
    Required Adapter
    django.db.backends.postgresql_psycopg2
    PostgreSQL
    django.db.backends.mysql
    MySQL
    django.db.backends.sqlite3
    SQLite
    No adapter needed.
    django.db.backends.oracle
    Oracle
    Note that for whichever database back-end you use, you’ll need to download and install the appropriate database adapter. Each one is available for free on the Web; just follow the links in the “Required Adapter” column in Table 5-1. If you’re on Linux, your distribution’s package-management system might offer convenient packages. (Look for packages called python-postgresql or python-psycopg, for example.)
    Example:
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
  • NAME tells Django the name of your database. For example:
    'NAME': 'mydb',
    If you’re using SQLite, specify the full filesystem path to the database file on your filesystem. For example:
    'NAME': '/home/django/mydata.db',
    As for where you put that SQLite database, we’re using the /home/django directory in this example, but you should pick a directory that works best for you.
  • USER tells Django which username to use when connecting to your database. For example: If you’re using SQLite, leave this blank.
  • PASSWORD tells Django which password to use when connecting to your database. If you’re using SQLite or have an empty password, leave this blank.
  • HOST tells Django which host to use when connecting to your database. If your database is on the same computer as your Django installation (i.e., localhost), leave this blank. If you’re using SQLite, leave this blank.
    MySQL is a special case here. If this value starts with a forward slash ('/') and you’re using MySQL, MySQL will connect via a Unix socket to the specified socket, for example:
    'HOST': '/var/run/mysql',
  • PORT tells Django which port to use when connecting to your database. If you’re using SQLite, leave this blank. Otherwise, if you leave this blank, the underlying database adapter will use whichever port is default for your given database server. In most cases, the default port is fine, so you can leave this blank.
Once you’ve entered those settings and saved settings.py, it’s a good idea to test your configuration. To do this, run python manage.py shell as in the last chapter, from within the mysite project directory. (As we pointed out last chapter manage.py shell is a way to run the Python interpreter with the correct Django settings activated. This is necessary in our case, because Django needs to know which settings file to use in order to get your database connection information.)
In the shell, type these commands to test your database configuration:
>>> from django.db import connection
>>> cursor = connection.cursor()
If nothing happens, then your database is configured properly. Otherwise, check the error message for clues about what’s wrong. Table 5-2 shows some common errors.
Table 5-2. Database Configuration Error Messages
Error MessageSolution
You haven’t set the ENGINE setting yet.Set the ENGINE setting to something other than an empty string. Valid values are in Table 5-1.
Environment variable DJANGO_SETTINGS_MODULE is undefined.Run the command python manage.py shellrather than python.
Error loading _____ module: No module named _____.You haven’t installed the appropriate database-specific adapter (e.g., psycopg or MySQLdb). Adapters are not bundled with Django, so it’s your responsibility to download and install them on your own.
_____ isn’t an available database backend.Set your ENGINE setting to one of the valid engine settings described previously. Perhaps you made a typo?
database _____ does not existChange the NAME setting to point to a database that exists, or execute the appropriateCREATE DATABASE statement in order to create it.
role _____ does not existChange the USER setting to point to a user that exists, or create the user in your database.
could not connect to serverMake sure HOST and PORT are set correctly, and make sure the database server is running.

Sunday, 23 August 2015

Day 10 - inheritance html

You can use as many levels of inheritance as needed. One common way of using inheritance is the following three-level approach:
  1. Create a base.html template that holds the main look and feel of your site. This is the stuff that rarely, if ever, changes.
  2. Create a base_SECTION.html template for each “section” of your site (e.g., base_photos.html andbase_forum.html). These templates extend base.html and include section-specific styles/design.
  3. Create individual templates for each type of page, such as a forum page or a photo gallery. These templates extend the appropriate section template.
This approach maximizes code reuse and makes it easy to add items to shared areas, such as section-wide navigation.

day 10 - Template

Template Loading


If you’re following along, open your settings.py and find the TEMPLATE_DIRS setting. By default, it’s an empty tuple, likely containing some auto-generated comments:
TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
)
"C:/project web/templates",
    # Always use forward slashes, even on Windows.
Note
Windows users, be sure to use forward slashes rather than backslashes. get_template() assumes a Unix-style file name designation.

from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    t = get_template('current_datetime.html')
    html = t.render(Context({'current_date': now}))
    return HttpResponse(html)
Moving along, create the current_datetime.html file within your template directory using the following template code:
<html><body>It is now {{ current_date }}.</body></html>
toring templates in subdirectories of your template directory is easy. In your calls to get_template(), just include the subdirectory name and a slash before the template name, like so:
t = get_template('dateapp/current_datetime.html')

or with shortcut


from django.shortcuts import render
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    return render(request, 'current_datetime.html', {'current_date': now})
The first argument to render() is the request, the second is the name of the template to use. The third argument, if given, should be a dictionary to use in creating a Context for that template. If you don’t provide a third argument, render() will use an empty dictionary.

Because render() is a small wrapper around get_template(), you can do the same thing with the second argument to render(), like this:
return render(request, 'dateapp/current_datetime.html', {'current_date': now})



day 10 - Filters use a pipe character

Filters use a pipe character

{{ name|lower }}
This displays the value of the {{ name }} variable after being filtered through the lower filter, which converts text to lowercase.




Filters can be chained – that is, they can be used in tandem such that the output of one filter is applied to the next. Here’s an example that takes the first element in a list and converts it to uppercase:
{{ my_list|first|upper }}
Some filters take arguments. A filter argument comes after a colon and is always in double quotes. For example:
{{ bio|truncatewords:"30" }}
This displays the first 30 words of the bio variable.
The following are a few of the most important filters. Appendix E covers the rest.
  • addslashes: Adds a backslash before any backslash, single quote, or double quote. This is useful if the produced text is included in a JavaScript string.
  • date: Formats a date or datetime object according to a format string given in the parameter, for example:
    {{ pub_date|date:"F j, Y" }}
    
    Format strings are defined in Appendix E.
  • length: Returns the length of the value. For a list, this returns the number of elements. For a string, this returns the number of characters. (Python experts, take note that this works on any Python object that knows how to determine its length – i.e., any object that has a __len__() method.)

10 day - forloop and if in template

Basic Template Tags and Filters


if
{% if today_is_weekend %}
    <p>Welcome to the weekend!</p>
{% endif %}

{% if athlete_list %}
    <p>Here are the athletes: {{ athlete_list }}.</p>
{% else %}
    <p>No athletes are available.</p>
    {% if coach_list %}
        <p>Here are the coaches: {{ coach_list }}.</p>
    {% endif %}
{% endif %}


for

{% for athlete in athlete_list %}
    <h1>{{ athlete.name }}</h1>
    <ul>
    {% for sport in athlete.sports_played %}
        <li>{{ sport }}</li>
    {% endfor %}
    </ul>
{% endfor %}

for and if

{% if athlete_list %}
    {% for athlete in athlete_list %}
        <p>{{ athlete.name }}</p>
    {% endfor %}
{% else %}
    <p>There are no athletes. Only computer programmers.</p>
{% endif %}

  • forloop.counter is always set to an integer representing the number of times the loop has been entered. This is one-indexed, so the first time through the loop, forloop.counter will be set to 1. Here’s an example:
    {% for item in todo_list %}
        <p>{{ forloop.counter }}: {{ item }}</p>
    {% endfor %}



  • forloop.parentloop is a reference to the forloop object for the parent loop, in case of nested loops. Here’s an example:
    {% for country in countries %}
        <table>
        {% for city in country.city_list %}
            <tr>
            <td>Country #{{ forloop.parentloop.counter }}</td>
            <td>City #{{ forloop.counter }}</td>
            <td>{{ city }}</td>
            </tr>
        {% endfor %}
        </table>
    {% endfor %}



it’s quite a common template requirement to compare two values and display something if they’re equal – and Django provides an {% ifequal %} tag for that purpose.
The {% ifequal %} tag compares two values and displays everything between {% ifequal %} and{% endifequal %} if the values are equal.
This example compares the template variables user and currentuser:
{% ifequal user currentuser %}
    <h1>Welcome!</h1>
{% endifequal %}