• Aucun résultat trouvé

Designing the Models

Dans le document Projects Django (Page 67-70)

You’re going to need several models to implement all of the features in your list, and a couple of them will be moderately complex. However, you can start with a simple one: the model that will represent categories for entries to be assigned to. Open up the weblog application’s models.pyfile, and add the following:

from django.db import models

class Category(models.Model):

title = models.CharField(max_length=250) slug = models.SlugField(unique=True) description = models.TextField() class Admin:

pass

def __unicode__(self):

return self.title

Most of this should be familiar after your first foray into Django models in the last chap-ter. The importstatement pulls in Django’s models package, which includes the base Model class and definitions for the different types of fields to represent data. You’ve already seen the CharField(this one has a longer max_lengthin order to allow for long category names), the Adminclass declaration to activate the admin interface, and the __unicode__()method (which, for this model, returns the value of the titlefield). But there are two new field types here:

SlugFieldand TextField.

The meaning of TextFieldis pretty intuitive. It’s meant to store a larger amount of text (in the database, it will become a TEXTcolumn), and will be used here to provide a useful description of the category.

SlugFieldis a bit more interesting. It’s meant to store a slug: a short, meaningful piece of text, composed entirely of characters that are safe to use in a URL and to be used in generating the URL for a particular object. This means, for example, that instead of having a URL like /categories?category_id=47, you could have/categories/programming/. This is useful to your site’s visitors (because it makes the URL meaningful and easier to remember) and for search engine indexing. URLs that have a relevant word in the URL often rank higher in Google and other search engines than URLs that don’t. The term slug, as befits Django’s heritage, comes from the newspaper industry, where it is used in preprint production and sometimes in wire formats as a shorter identifier for a news story. Note that I’ve added an extra argument to SlugField:unique=True. Since the slug is going to be used in the URL and the same URL can’t refer to two different categories, it needs to be unique. Django’s administrative interface will

enforce uniqueness for this field, and manage.py syncdbwill create the database table with a UNIQUEconstraint for that column.

It’s useful when developing an application to stop every once in a while and actually try it out. So go back to the cms project, open up its settings file, and add coltrane—the new weblog application—to its INSTALLED_APPSsetting:

INSTALLED_APPS = (

'django.contrib.auth',

'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', 'django.contrib.flatpages', 'cms.search',

'coltrane', )

Because it’s directly on the Python path, just adding coltranewill work. Next run python manage.py syncdbto install the table for the Categorymodel and launch the development server. The admin index page will look like that shown in Figure 4-1.

Figure 4-1.The Django admin interface with the Category model

You can see that the Categorymodel shows up, but it’s labeled “Categorys.” That’s no good. Django’s admin interface generates that label from the name of the model class and tries to pluralize it by adding an “s,” which works most of the time. It doesn’t always work,

though, and when it doesn’t Django lets you specify the correct plural name. Go back to the weblog’s models.pyfile and edit the Categorymodel class to look like the following:

class Category(models.Model):

title = models.CharField(max_length=250) slug = models.SlugField(unique=True) description = models.TextField() class Meta:

verbose_name_plural = "Categories"

class Admin:

pass

def __unicode__(self):

return self.title

Once you save the file and refresh the admin index page in your browser, you should see something similar to what’s shown in Figure 4-2.

Figure 4-2.The correct pluralization of the Category model

Because you often need to provide extra meta-information about a model, Django lets you add an inner class, named Meta, which can specify a large number of common options. In this case, you’re using an option called verbose_name_plural, which will return a pluralized name for the model class whenever it’s needed. (There’s also a verbose_nameoption, which can specify a singular version if it differs significantly from the class name, but you don’t need it

here.) You’ll see a number of other useful options for the inner Metaclass as you flesh out the weblog’s models.

If you click in the admin interface to add a category, you’ll see the appropriate fields in a nice form: title,slug, and description. But adding a category this way will reveal another shortcoming. Most of the time, the value for the slugfield will probably be similar or even identical to the value for the titlefield (for example, a Programming category should proba-bly have a slug like “programming”). Having to manually type the slug every time would be tedious, so why not have it automatically generated from the title, and then let the user manu-ally change it if necessary? This is easy enough to do. Just change the definition of the slug field to look like this:

slug = models.SlugField(prepopulate_from=['title'], unique=True)

Then save the models.pyfile and add a category. The prepopulate_fromargument will turn on a helpful piece of JavaScript in Django’s administrative interface, and it will automatically fill in a suggested slug as you type a value into the titlefield. Note that prepopulate_fromgets a list: this means you could specify multiple fields to try to draw the slug value from, which isn’t common but is sometimes useful. The JavaScript that generates slugs is also smart enough to recognize, and omit, words like a, an, the, and so on. These are called stop words and generally aren’t useful to have in a slug.

Also, note that when Django creates the database table for this model, it will add an index to the slug column. You can manually tell Django to do this with any field (by using the option db_index=Truefor the field), but SlugFieldwill get one automatically, providing a perform-ance boost in the common case of using a slug from a URL to perform database queries.

Dans le document Projects Django (Page 67-70)