Django

Code

Changeset 2833

Show
Ignore:
Timestamp:
05/04/06 20:56:29 (3 years ago)
Author:
adrian
Message:

Finished proofreading docs/model-api.txt

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/docs/model-api.txt

    r2829 r2833  
    12991299======== 
    13001300 
    1301 The Manager is the interface through which database query operations 
    1302 are provided to Django applications. At least one Manager exists for 
    1303 every model in a Django application. 
    1304  
    1305 By default, Django will add a Manager with the name of ``objects`` to 
    1306 every Django model. However, if you wish to use ``objects`` as a field 
    1307 name, or if you wish to use a name other than ``objects`` for the Manager, 
    1308 you can rename the Manager on a per-model basis. To rename the Manager 
    1309 for a given class, define a class attribute of type models.Manager() 
    1310 on that model. For example:: 
     1301A ``Manager`` is the interface through which database query operations are 
     1302provided to Django models. At least one ``Manager`` exists for every model in 
     1303a Django application. 
     1304 
     1305The way ``Manager`` classes work is documented in the `Retrieving objects`_ 
     1306section of the database API docs, but this section specifically touches on 
     1307model options that customize ``Manager`` behavior. 
     1308 
     1309Manager names 
     1310------------- 
     1311 
     1312By default, Django adds a ``Manager`` with the name ``objects`` to every Django 
     1313model class. However, if you want to use ``objects`` as a field name, or if you 
     1314want to use a name other than ``objects`` for the ``Manager``, you can rename 
     1315it on a per-model basis. To rename the ``Manager`` for a given class, define a 
     1316class attribute of type ``models.Manager()`` on that model. For example:: 
    13111317 
    13121318    from django.db import models 
     
    13161322        people = models.Manager() 
    13171323 
    1318 In this example, ``Person.objects.all()`` will generate an error, but 
    1319 ``Person.people.all()`` will provide a list of all ``Person`` objects. 
    1320  
    1321 Managers can also be customized. This is achieved by extending the 
    1322 base Manager class, and instantiating the new Manager on your model. 
    1323 There are two reasons that you may want to customize a Manager: firstly, 
    1324 to add utility methods to the Manager, and secondly, to modify the 
    1325 initial Query Set provided by the Manager. 
    1326  
    1327 To modify the initial Query Set provided by a Manager, override the 
    1328 ``get_query_set()`` method to return a Query Set with the properties 
    1329 you require. For example:: 
    1330  
    1331     class PersonManager(models.Manager): 
    1332         # Add some custom behavior to the Manager 
    1333         def move_house(self): 
    1334             # Some logic to help a person move house 
    1335  
    1336         # Modify the initial Query Set provided by the manager 
     1324Using this example model, ``Person.objects`` will generate an 
     1325``AttributeError`` exception, but ``Person.people.all()`` will provide a list 
     1326of all ``Person`` objects. 
     1327 
     1328Custom Managers 
     1329--------------- 
     1330 
     1331You can use a custom ``Manager`` in a particular model by extending the base 
     1332``Manager`` class and instantiating your custom ``Manager`` in your model. 
     1333 
     1334There are two reasons you might want to customize a ``Manager``: to add extra 
     1335``Manager`` methods, and/or to modify the initial ``QuerySet`` the ``Manager`` 
     1336returns. 
     1337 
     1338Adding extra Manager methods 
     1339~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     1340 
     1341Adding extra ``Manager`` methods is the preferred way to add "table-level" 
     1342functionality to your models. (For "row-level" functionality -- i.e., functions 
     1343that act on a single instance of a model object -- use _`Model methods`, not 
     1344custom ``Manager`` methods.) 
     1345 
     1346A custom ``Manager`` method can return anything you want. It doesn't have to 
     1347return a ``QuerySet``. 
     1348 
     1349For example, this custom ``Manager`` offers a method ``with_counts()``, which 
     1350returns a list of all ``OpinionPoll`` objects, each with an extra 
     1351``num_responses`` attribute that is the result of an aggregate query:: 
     1352 
     1353    class PollManager(models.Manager): 
     1354        def with_counts(self): 
     1355            from django.db import connection 
     1356            cursor = connection.cursor() 
     1357            cursor.execute(""" 
     1358                SELECT p.id, p.question, p.poll_date, COUNT(*) 
     1359                FROM polls_opinionpoll p, polls_response r 
     1360                WHERE p.id = r.poll_id 
     1361                GROUP BY 1, 2, 3 
     1362                ORDER BY 3 DESC""") 
     1363            result_list = [] 
     1364            for row in cursor.fetchall(): 
     1365                p = self.model(id=row[0], question=row[1], poll_date=row[2]) 
     1366                p.num_responses = row[3] 
     1367                result_list.append(p) 
     1368            return result_list 
     1369 
     1370    class OpinionPoll(models.Model): 
     1371        question = models.CharField(maxlength=200) 
     1372        poll_date = models.DateField() 
     1373        objects = PollManager() 
     1374 
     1375    class Response(models.Model): 
     1376        poll = models.ForeignKey(Poll) 
     1377        person_name = models.CharField(maxlength=50) 
     1378        response = models.TextField() 
     1379 
     1380With this example, you'd use ``OpinionPoll.objects.with_counts()`` to return 
     1381that list of ``OpinionPoll`` objects with ``num_responses`` attributes. 
     1382 
     1383Another thing to note about this example is that ``Manager`` methods can 
     1384access ``self.model`` to get the model class to which they're attached. 
     1385 
     1386Modifying initial Manager QuerySets 
     1387~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     1388 
     1389A ``Manager``'s base ``QuerySet`` returns all objects in the system. For 
     1390example, using this model:: 
     1391 
     1392    class Book(models.Model): 
     1393        title = models.CharField(maxlength=100) 
     1394        author = models.CharField(maxlength=50) 
     1395 
     1396...the statement ``Book.objects.all()`` will return all books in the database. 
     1397 
     1398You can override a ``Manager``'s base ``QuerySet`` by overriding the 
     1399``Manager.get_query_set()`` method. ``get_query_set()`` should return a 
     1400``QuerySet`` with the properties you require. 
     1401 
     1402For example, the following model has *two* ``Manager``s -- one that returns 
     1403all objects, and one that returns only the books by Roald Dahl:: 
     1404 
     1405    # First, define the Manager subclass. 
     1406    class DahlBookManager(models.Manager): 
    13371407        def get_query_set(self): 
    1338             return super(Manager, self).get_query_set().filter(name__startswith="Fred") 
    1339  
    1340     class Person(models.Model): 
    1341         #... 
    1342         objects = PersonManager() 
    1343  
    1344 In this example, ``Person.objects.all()`` will only return people whose name starts 
    1345 with "Fred"; ``Person.objects.move_house()`` will also be available. 
    1346  
    1347 If required, you can add multiple Managers to a model. Every Manager attribute 
    1348 added to a model can be accessed and used as a manager. This is an easy way 
    1349 to define common filters types for your models. For example, the model:: 
     1408            return super(Manager, self).get_query_set().filter(author='Roald Dahl') 
     1409 
     1410    # Then hook it into the Book model explicitly. 
     1411    class Book(models.Model): 
     1412        title = models.CharField(maxlength=100) 
     1413        author = models.CharField(maxlength=50) 
     1414 
     1415        objects = models.Manager() # The default manager. 
     1416        dahl_objects = DahlBookManager() # The Dahl-specific manager. 
     1417 
     1418With this sample model, ``Book.objects.all()`` will return all books in the 
     1419database, but ``Book.dahl_objects.all()`` will only return the ones written by 
     1420Roald Dahl. 
     1421 
     1422Of course, because ``get_query_set()`` returns a ``QuerySet`` object, you can 
     1423use ``filter()``, ``exclude()`` and all the other ``QuerySet`` methods on it. 
     1424So these statements are all legal:: 
     1425 
     1426    Book.dahl_objects.all() 
     1427    Book.dahl_objects.filter(title='Matilda') 
     1428    Book.dahl_objects.count() 
     1429 
     1430This example also pointed out another interesting technique: using multiple 
     1431managers on the same model. You can attach as many ``Manager()`` instances to 
     1432a model as you'd like. This is an easy way to define common "filters" for your 
     1433models. 
     1434 
     1435For example:: 
    13501436 
    13511437    class MaleManager(models.Manager): 
     
    13581444 
    13591445    class Person(models.Model): 
    1360         #... 
     1446        first_name = models.CharField(maxlength=50) 
     1447        last_name = models.CharField(maxlength=50) 
     1448        sex = models.CharField(maxlength=1, choices=(('M', 'Male'), ('F', 'Female'))) 
    13611449        people = models.Manager() 
    13621450        men = MaleManager() 
    13631451        women = FemaleManager() 
    13641452 
    1365 ... will allow end users to request ``Person.men.all()``, ``Person.women.all()``, 
     1453This example allows you to request ``Person.men.all()``, ``Person.women.all()``, 
    13661454and ``Person.people.all()``, yielding predictable results. 
    13671455 
    1368 If you are going to install a customized Manager, be warned that the first 
    1369 Manager that Django encounters in a model definition has special status. 
    1370 Django interprets the first Manager defined in a class as the default Manager. 
    1371 Certain operations use the default Manager to obtain lists of objects, so it 
    1372 is generally a good idea for the first Manager to be relatively unfiltered. 
    1373 In the last example, ``people`` is defined first - so the default Manager 
    1374 will include everyone. 
     1456If you use custom ``Manager`` objects, take note that the first ``Manager`` 
     1457Django encounters (in order by which they're defined in the model) has a 
     1458special status. Django interprets the first ``Manager`` defined in a class as 
     1459the "default" ``Manager``. Certain operations -- such as Django's admin site -- 
     1460use the default ``Manager`` to obtain lists of objects, so it's generally a 
     1461good idea for the first ``Manager`` to be relatively unfiltered. In the last 
     1462example, the ``people`` ``Manager`` is defined first -- so it's the default 
     1463``Manager``. 
    13751464 
    13761465Model methods 
    13771466============= 
    13781467 
    1379 There are a number of methods you can define on model objects to control the 
    1380 object's behavior.  First, any methods you define will be available as methods 
    1381 of object instances. For example:: 
    1382  
    1383     class Pizza(models.Model): 
    1384         # ... 
    1385  
    1386         def is_disgusting(self): 
    1387             return "anchovies" in [topping.name for topping in self.toppings.all()] 
    1388  
    1389 Now, every ``Pizza`` object will have a ``is_disgusting()`` method. 
    1390  
    1391 See `Giving models custom methods`_ for a full example. 
    1392  
    1393 .. _Giving models custom methods: http://www.djangoproject.com/documentation/models/custom_methods/ 
     1468Define custom methods on a model to add custom "row-level" functionality to 
     1469your objects. Whereas ``Manager`` methods are intended to do "table-wide" 
     1470things, model methods should act on a particular model instance. 
     1471 
     1472This is a valuable technique for keeping business logic in one place -- the 
     1473model. 
     1474 
     1475For example, this model has a few custom methods:: 
     1476 
     1477    class Person(models.Model): 
     1478        first_name = models.CharField(maxlength=50) 
     1479        last_name = models.CharField(maxlength=50) 
     1480        birth_date = models.DateField() 
     1481        address = models.CharField(maxlength=100) 
     1482        city = models.CharField(maxlength=50) 
     1483        state = models.USStateField() # Yes, this is America-centric... 
     1484 
     1485    def baby_boomer_status(self): 
     1486        "Returns the person's baby-boomer status." 
     1487        import datetime 
     1488        if datetime.date(1945, 8, 1) <= self.birth_date <= datetime.date(1964, 12, 31): 
     1489            return "Baby boomer" 
     1490        if self.birth_date < datetime.date(1945, 8, 1): 
     1491            return "Pre-boomer" 
     1492        return "Post-boomer" 
     1493 
     1494    def is_midwestern(self): 
     1495        "Returns True if this person is from the Midwest." 
     1496        return self.state in ('IL', 'WI', 'MI', 'IN', 'OH', 'IA', 'MO') 
     1497 
     1498    def _get_full_name(self): 
     1499        "Returns the person's full name." 
     1500        return '%s %s' % (self.first_name, self.last_name) 
     1501    full_name = property(_get_full_name) 
     1502 
     1503The last method in this example is a *property*. `Read more about properties`_. 
     1504 
     1505.. _Read more about properties: http://www.python.org/download/releases/2.2/descrintro/#property 
    13941506 
    13951507A few object methods have special meaning: 
    13961508 
    13971509``__str__`` 
    1398     Django uses ``str(obj)`` in a number of places, most notably as the value 
    1399     inserted into a template when it displays an object. Thus, you should always 
    1400     return a nice, human-readable string for the object's ``__str__``. 
    1401  
    1402     Although defining ``__str__()`` isn't required, it's strongly encouraged. 
    1403  
    1404     See `Adding str`_ for a full example. 
    1405  
    1406     .. _Adding str: http://www.djangoproject.com/documentation/models/repr/ 
     1510----------- 
     1511 
     1512``__str__()`` is a Python "magic method" that defines what should be returned 
     1513if you call ``str()`` on the object. Django uses ``str(obj)`` in a number of 
     1514places, most notably as the value displayed to render an object in the Django 
     1515admin site and as the value inserted into a template when it displays an 
     1516object. Thus, you should always return a nice, human-readable string for the 
     1517object's ``__str__``. Although this isn't required, it's strongly encouraged. 
     1518 
     1519For example:: 
     1520 
     1521    class Person(models.Model): 
     1522        first_name = models.CharField(maxlength=50) 
     1523        last_name = models.CharField(maxlength=50) 
     1524 
     1525        def __str__(self): 
     1526            return '%s %s' % (self.first_name, self.last_name) 
    14071527 
    14081528``get_absolute_url`` 
    1409     Define a ``get_absolute_url`` method to tell Django how to calculate the 
    1410     URL for an object. For example:: 
    1411  
    1412         def get_absolute_url(self): 
    1413             return "/pizzas/%i/" % self.id 
    1414  
    1415     Django uses this in its admin interface. If an object defines 
    1416     ``get_absolute_url``, the object detail page will have a "View on site" 
    1417     link that will jump you directly to the object's public view. 
    1418  
    1419     It's good practice to use ``get_absolute_url()`` in templates, instead of 
    1420     hard-coding your objects' URLs. 
    1421  
    1422 Module-level methods 
    14231529-------------------- 
    14241530 
    1425 If you want to add a method to the Model, rather than instances of the model, 
    1426 you can use the Python ``staticmethod`` and ``classmethod`` operators. For 
    1427 example:: 
    1428  
    1429     class Pizza(models.Model): 
    1430         # ... 
    1431  
    1432         def get_pizzas_to_deliver(): 
    1433             return get_list(delivered__exact=False) 
    1434         get_pizzas_to_deliver = staticmethod(get_pizzas_to_deliver) 
    1435  
    1436 Or, using Python 2.4 decorators:: 
    1437  
    1438     # ... 
    1439     @staticmethod 
    1440     def get_pizzas_to_deliver(): 
    1441         # ... 
    1442  
    1443 This will make the top-level ``pizzas`` module have a ``get_pizzas_to_deliver()`` 
    1444 method:: 
    1445  
    1446     >>> from pizza_hut.models import Pizza 
    1447     >>> Pizza.get_pizzas_to_deliver() 
    1448     [ ... ] 
    1449  
    1450 Manipulator methods 
    1451 ------------------- 
    1452  
    1453 (The functionality in this section is going away soon. This documentation is 
    1454 provided only for legacy purposes at this point.) 
    1455  
    1456 Similarly, you can add methods to the object's manipulators by defining methods 
    1457 that being with "_manipulator_". This is most useful for providing custom 
    1458 validators for certain fields, because manipulators automatically call any 
    1459 method that begins with "validate":: 
    1460  
    1461     class Pizza(models.Model): 
    1462         # ... 
    1463  
    1464         def _manipulator_validate_customer_id(self, field_data, all_data): 
    1465             from django.core import validators 
    1466             from django.conf.settings import BAD_CUSTOMER_IDS 
    1467  
    1468             if int(field_data) in BAD_CUSTOMER_IDS: 
    1469                 raise validators.ValidationError, "We don't deliver to this customer." 
     1531Define a ``get_absolute_url()`` method to tell Django how to calculate the 
     1532URL for an object. For example:: 
     1533 
     1534    def get_absolute_url(self): 
     1535        return "/people/%i/" % self.id 
     1536 
     1537Django uses this in its admin interface. If an object defines 
     1538``get_absolute_url()``, the object-editing page will have a "View on site" 
     1539link that will jump you directly to the object's public view, according to 
     1540``get_absolute_url()``. 
     1541 
     1542Also, a couple of other bits of Django, such as the syndication-feed framework, 
     1543use ``get_absolute_url()`` as a convenience to reward people who've defined the 
     1544method. 
     1545 
     1546It's good practice to use ``get_absolute_url()`` in templates, instead of 
     1547hard-coding your objects' URLs. For example, this template code is bad:: 
     1548 
     1549    <a href="/people/{{ object.id }}/">{{ object.name }}</a> 
     1550 
     1551But this template code is good:: 
     1552 
     1553    <a href="{{ object.get_absolute_url }}">{{ object.name }}</a> 
     1554 
     1555(Yes, we know ``get_absolute_url()`` couples URLs to models, which violates the 
     1556DRY principle, because URLs are defined both in a URLconf and in the model. 
     1557This is a rare case in which we've intentionally violated that principle for 
     1558the sake of convenience. With that said, we're working on an even cleaner way 
     1559of specifying URLs in a more DRY fashion.) 
    14701560 
    14711561Executing custom SQL 
     
    14731563 
    14741564Feel free to write custom SQL statements in custom model methods and 
    1475 module-level methods. The object ``django.db.connection`` object represents 
    1476 the current database connection. To use it, call ``connection.cursor()`` to 
    1477 get a cursor object. Then, call ``cursor.execute(sql, [params])`` 
    1478 to execute the SQL and ``cursor.fetchone()`` or ``cursor.fetchall()`` to return 
    1479 the resulting rows. Example:: 
     1565module-level methods. The object ``django.db.connection`` represents the 
     1566current database connection. To use it, call ``connection.cursor()`` to get a 
     1567cursor object. Then, call ``cursor.execute(sql, [params])`` to execute the SQL 
     1568and ``cursor.fetchone()`` or ``cursor.fetchall()`` to return the resulting 
     1569rows. Example:: 
    14801570 
    14811571    def my_custom_sql(self): 
     
    14951585        connection.commit() 
    14961586 
    1497 ``connection`` and ``cursor`` simply use the standard `Python DB-API`_. If you're not 
    1498 familiar with the Python DB-API, note that the SQL statement in 
     1587``connection`` and ``cursor`` simply use the standard `Python DB-API`_. If 
     1588you're not familiar with the Python DB-API, note that the SQL statement in 
    14991589``cursor.execute()`` uses placeholders, ``"%s"``, rather than adding parameters 
    15001590directly within the SQL. If you use this technique, the underlying database 
    15011591library will automatically add quotes and escaping to your parameter(s) as 
    1502 necessary. 
     1592necessary. (Also note that Django expects the ``"%s"`` placeholder, *not* the 
     1593``"?"`` placeholder, which is used by the SQLite Python bindings. This is for 
     1594the sake of consistency and sanity.) 
    15031595 
    15041596A final note: If all you want to do is a custom ``WHERE`` clause, you can just 
     
    15091601.. _Other lookup options: http://www.djangoproject.com/documentation/db_api/#extra-params-select-where-tables 
    15101602 
     1603Models across files 
     1604=================== 
     1605 
     1606It's perfectly OK to relate a model to one from another app. To do this, just 
     1607import the related model at the top of the model that holds your model. Then, 
     1608just refer to the other model class wherever needed. For example:: 
     1609 
     1610    from mysite.geography.models import ZipCode 
     1611 
     1612    class Restaurant(models.Model): 
     1613        # ... 
     1614        zip_code = models.ForeignKey(ZipCode) 
     1615 
    15111616Using models 
    15121617============ 
    15131618 
    1514 Once you have created your model, you have to tell Django about your new application. 
    1515 This is done by editing your settings file and adding the name of the module that 
    1516 contains your models module to the ``INSTALLED_APPS`` tuple. 
    1517  
    1518 For example, if the models for your application are contained in the module 
    1519 ``project.myapp.models`` (the package structure that is created for an application 
    1520 by the ``django-admin.py startapp`` script), ``INSTALLED_APPS`` should read, in part:: 
     1619Once you have created your models, the final step is to tell Django you're 
     1620going to *use* those models. 
     1621 
     1622Do this by editing your settings file and changing the ``INSTALLED_APPS`` 
     1623setting to add the name of the module that contains your ``models.py``. 
     1624 
     1625For example, if the models for your application live in the module 
     1626``mysite.myapp.models`` (the package structure that is created for an 
     1627application by the ``manage.py startapp`` script), ``INSTALLED_APPS`` should 
     1628read, in part:: 
    15211629 
    15221630    INSTALLED_APPS = ( 
    15231631        #... 
    1524         project.myapp
     1632        'mysite.myapp'
    15251633        #... 
    15261634    ) 
    1527  
    1528 Models across files 
    1529 =================== 
    1530  
    1531 It's perfectly OK to relate a model to one from another module. To do this, 
    1532 just import the model module at the top of your model module. Then, just 
    1533 refer to the other model class wherever needed. For example:: 
    1534  
    1535     from myproject.otherapp import Site 
    1536  
    1537     class MyModel(models.Model): 
    1538         # ... 
    1539         sites = models.ManyToManyField(Site)