From d6ba2d477c8db8f209bcd82b7600bd78d7696843 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Thu, 13 Apr 2006 23:52:35 +0000 Subject: [PATCH] magic-removal: Added more updates to db-api documentation. Still requires more work. Also requires entry in model-api about creating new Managers. git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@2697 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/db-api.txt | 597 ++++++++++++++++++++++++--------------------- docs/model-api.txt | 5 + 2 files changed, 318 insertions(+), 284 deletions(-) diff --git a/docs/db-api.txt b/docs/db-api.txt index 2c89704623..db3fce9358 100644 --- a/docs/db-api.txt +++ b/docs/db-api.txt @@ -15,10 +15,13 @@ Throughout this reference, we'll refer to the following Poll application:: question = models.CharField(maxlength=255) pub_date = models.DateTimeField() expire_date = models.DateTimeField() - + def __repr__(self): return self.question + class Meta: + get_latest_by = 'pub_date' + class Choice(models.Model): poll = models.ForeignKey(Poll, edit_inline=meta.TABULAR, num_in_admin=10, min_num_in_admin=5) @@ -28,212 +31,85 @@ Throughout this reference, we'll refer to the following Poll application:: def __repr__(self): return self.choice +and the following Django sample session:: + + >>> from datetime import datetime + >>> p1 = Poll(slug='whatsup', question="What's up?", + ... pub_date=datetime(2005, 2, 20), expire_date=datetime(2005, 4, 20)) + >>> p1.save() + >>> p2 = Poll(slug='name', question="What's your name?", + ... pub_date=datetime(2005, 3, 20), expire_date=datetime(2005, 3, 25)) + >>> p2.save() + >>> Poll.objects.all() + [What's up?, What's your name?] + How Queries Work ================ Querying in Django is based upon the construction and evaluation of Query Sets. -A Query Set is a representation of a query. +A Query Set is a database-independent representation of a query. It can be +thought of as a representation of a group of objects that meet a given set +of criteria. However, the members of the set are not determined until the +Query Set is formally evaluated. -When you compose a query using Django, you construct a Query Set; when you want -to evaluate the query, you iterate over or slice the Query Set that represents -your query. +To compose a Query using Django, you obtain an initial a Query Set. This +Query Set can then be refined using a range of operations. When you have +a Query Set that meets your needs, it can be evaluated (using iterators, slicing, +or one of a range of other techniques), yielding an object or list of objects +that meet the specifications of the Query Set. -Every Django model has a Manager object that acts as a factory for new query sets. +Obtaining a Query Set +===================== -The manager has a special factory method for creating Suery Sets:: +Query Sets are obtained using the Manager object on a model. Every model +has at least one Manager; by default, the Manager is called ``objects``. + +See the `Managers`_ section of the Model API for more details on the role +and construction of Managers. + +.. _Managers: http://www.djangoproject.com/documentation/model_api/#managers + +The manager has a special factory method for creating Query Sets:: queryset = Poll.objects.all() This creates a new Query Set that matches all the objects of the given class. -Query Set evaluation -==================== - -Once you have constructed a Query Set to meet your needs - -A Query Set is an iterable object:: - - queryset = Poll.objects.all() - for p in queryset: - print p - -Query Sets can also be sliced:: - - fifth_poll = queryset[4] - all_polls_but_the_first_two = queryset[2:] - -Regardless of the method used to extract data from the Query Set, upon first -evaluation, the query will be executed on the database, and the results cached. -Subsequent evaluations on the database will reuse the cached results. - -As an alternative to iteration and slicing, you can use one of the -following functions. These functions do not populate or effect the cache: - -get(\**kwargs) --------------- - -Returns the object matching the given lookup parameters, which should be in -the format described in "Field lookups" below. Raises a module-level -``DoesNotExist`` exception if an object wasn't found for the given parameters. -Raises ``AssertionError`` if more than one object was found. - -count() -------- - -Returns an integer representing the number of objects in the database matching -the Query Set. ``count()`` never raises exceptions - -Depending on which database you're using (e.g. PostgreSQL vs. MySQL), this may -return a long integer instead of a normal Python integer. - -in_bulk(id_list) ----------------- - -Takes a list of IDs and returns a dictionary mapping each ID to an instance of -the object with the given ID. Also takes optional keyword lookup arguments, -which should be in the format described in "Field lookups" below. Here's an -example, using the ``Poll`` model defined above:: - - >>> from datetime import datetime - >>> p1 = Poll(slug='whatsup', question="What's up?", - ... pub_date=datetime(2005, 2, 20), expire_date=datetime(2005, 3, 20)) - >>> p1.save() - >>> p2 = Poll(slug='name', question="What's your name?", - ... pub_date=datetime(2005, 3, 20), expire_date=datetime(2005, 4, 20)) - >>> p2.save() - >>> Poll.objects.all() - [What's up?, What's your name?] - >>> Poll.objects.in_bulk([1]) - {1: What's up?} - >>> Poll.objects.in_bulk([1, 2]) - {1: What's up?, 2: What's your name?} - >>> Poll.objects.in_bulk([]) - {} - -latest(field_name=None) ------------------------ - -Returns the latest object, according to the model's 'get_latest_by' -option or optional given field_name. - -delete() --------- - -Delete the members of the query set. - -Query Set construction -====================== - -Any Query Set (evaluated or not) can be refined by calling one of the following methods: - -filter(\**kwargs) -------------------- - -Returns a new Query Set containing objects that match the given lookup parameters. -Lookup parameters should be in the format described in "Field lookups" below. - -``filter()`` will always return a list. - -exclude(\**kwargs) -------------------- - -As for filter, but negated. - -distinct() ----------- - -If ``distinct`` is True, only distinct rows will be returned. This is equivalent -to a ``SELECT DISTINCT`` SQL clause. You can use this with ``get_values()`` to -get distinct values. For example, this returns the distinct first_names:: - - >>> people.get_values(fields=['first_name'], distinct=True) - [{'first_name': 'Adrian'}, {'first_name': 'Jacob'}, {'first_name': 'Simon'}] - -values(\*fields) ---------------------- - -Just like ``filter()``, except it returns a list of dictionaries instead of -model-instance objects. - -It accepts an optional parameter, ``fields``, which should be a list or tuple -of field names. If you don't specify ``fields``, each dictionary in the list -returned by ``get_values()`` will have a key and value for each field in the -database table. If you specify ``fields``, each dictionary will have only the -field keys/values for the fields you specify. Here's an example, using the -``Poll`` model defined above:: - - >>> from datetime import datetime - >>> p1 = Poll(slug='whatsup', question="What's up?", - ... pub_date=datetime(2005, 2, 20), expire_date=datetime(2005, 3, 20)) - >>> p1.save() - >>> p2 = Poll(slug='name', question="What's your name?", - ... pub_date=datetime(2005, 3, 20), expire_date=datetime(2005, 4, 20)) - >>> p2.save() - >>> Poll.objects.all() - [What's up?, What's your name?] - >>> Poll.objects.get_values() - [{'id': 1, 'slug': 'whatsup', 'question': "What's up?", 'pub_date': datetime.datetime(2005, 2, 20), 'expire_date': datetime.datetime(2005, 3, 20)}, - {'id': 2, 'slug': 'name', 'question': "What's your name?", 'pub_date': datetime.datetime(2005, 3, 20), 'expire_date': datetime.datetime(2005, 4, 20)}] - >>> Poll.objects.get_values(fields=['id', 'slug']) - [{'id': 1, 'slug': 'whatsup'}, {'id': 2, 'slug': 'name'}] - -Use ``get_values()`` when you know you're only going to need a couple of field -values and you won't need the functionality of a model instance object. It's -more efficient to select only the fields you need to use. - -dates(field, kind, order='ASC') -------------------------------- - -Every manager has a ``dates()`` method, which returns a list of -``datetime.datetime`` objects representing all available dates with the given -filters (if any) and of the given scope, as defined by the ``kind`` argument. - -``field`` should be the name of a ``DateField`` or ``DateTimeField`` of your -model. - -``kind`` should be either ``"year"``, ``"month"`` or ``"day"``. Each -``datetime.datetime`` object in the result list is "truncated" to the given -``type``. - - * ``"year"`` returns a list of all distinct year values for the field. - * ``"month"`` returns a list of all distinct year/month values for the field. - * ``"day"`` returns a list of all distinct year/month/day values for the field. - -``order``, which defaults to ``'ASC'``, should be either ``"ASC"`` or ``"DESC"``. -This specifies how to order the results. - -Here's an example, using the ``Poll`` model defined above:: - - >>> from datetime import datetime - >>> p1 = Poll(slug='whatsup', question="What's up?", - ... pub_date=datetime(2005, 2, 20), expire_date=datetime(2005, 3, 20)) - >>> p1.save() - >>> p2 = Poll(slug='name', question="What's your name?", - ... pub_date=datetime(2005, 3, 20), expire_date=datetime(2005, 4, 20)) - >>> p2.save() - >>> Poll.objects.dates('pub_date', 'year') - [datetime.datetime(2005, 1, 1)] - >>> Poll.objects.dates('pub_date', 'month') - [datetime.datetime(2005, 2, 1), datetime.datetime(2005, 3, 1)] - >>> Poll.objects.dates('pub_date', 'day') - [datetime.datetime(2005, 2, 20), datetime.datetime(2005, 3, 20)] - >>> Poll.objects.dates('pub_date', 'day', order='DESC') - [datetime.datetime(2005, 3, 20), datetime.datetime(2005, 2, 20)] - >>> Poll.objects.filter(question__contains='name').dates('pub_date', 'day') - [datetime.datetime(2005, 3, 20)] - - -Manager Shortcuts -================= - -As a convenient shortcut, all of these Query Set functions (with the -exception of delete) can be accessed from the Manager object itself. -The following queries are identical:: +As a convenient shortcut, all of these Query Set construction methods +can be accessed from the Manager object itself. +The following two queries are identical:: Poll.objects.all().filter(question__startswith="What") Poll.objects.filter(question__startswith="What") + +Query Set Refinement +==================== + +The default Query Set returned by the Manager contains all objects of the +Model type. In order to be useful, + +Any Query Set can be refined by calling one of the following methods: + +filter(\**kwargs) + Returns a new Query Set containing objects that match the given lookup parameters. + +exclude(\**kwargs) + Return a new Query Set containing objects that do not match the given lookup parameters. + +Lookup parameters should be in the format described in "Field lookups" below. + +Query Set refinements can be chained together:: + + Poll.objects.filter(question__startswith="What").exclude().filter(...) + +Query Sets can also be stored and reused:: + + q1 = Poll.objects.filter() + q2 = q1.exclude() + q3 = q1.filter() + Field lookups ============= @@ -329,8 +205,80 @@ If you pass an invalid keyword argument, the function will raise ``TypeError``. .. _`Keyword Arguments`: http://docs.python.org/tut/node6.html#SECTION006720000000000000000 +Query Set evaluation +==================== + +Once you have constructed a Query Set to meet your needs, it must be evaluated +to return the objects that are contained in the set. This can be achieved in + +A Query Set is an iterable object:: + + queryset = Poll.objects.all() + for p in queryset: + print p + +Query Sets can also be sliced:: + + fifth_poll = queryset[4] + all_polls_but_the_first_two = queryset[2:] + + +If you really need to have a . :: + querylist = list(Poll.objects.all()) + +However - be warned; if you use these approaches, + +Regardless of whether you iterate or slice the Query Set, + +upon first evaluation, the query will be executed on the database, and the results cached. +Subsequent evaluations of the Query Set reuse the cached results. + +As an alternative to iteration and slicing, you can use one of the +following functions. These functions do not populate or effect the cache: + +get(\**kwargs) +-------------- + +Returns the object matching the given lookup parameters, which should be in +the format described in _`Field lookups`. Raises a module-level +``DoesNotExist`` exception if an object wasn't found for the given parameters. +Raises ``AssertionError`` if more than one object was found. + +count() +------- + +Returns an integer representing the number of objects in the database matching +the Query Set. ``count()`` never raises exceptions. + +Depending on which database you're using (e.g. PostgreSQL vs. MySQL), this may +return a long integer instead of a normal Python integer. + +in_bulk(id_list) +---------------- + +Takes a list of IDs and returns a dictionary mapping each ID to an instance of +the object with the given ID. For example:: + + >>> Poll.objects.in_bulk([1]) + {1: What's up?} + >>> Poll.objects.in_bulk([1, 2]) + {1: What's up?, 2: What's your name?} + >>> Poll.objects.in_bulk([]) + {} + +latest(field_name=None) +----------------------- + +Returns the latest object, according to the model's 'get_latest_by' +Meta option, or using the field_name provided. For example:: + + >>> Poll.objects.latest() + What's up? + >>> Poll.objects.latest('expire_date') + What's your name? + OR lookups ----------- +========== By default, keyword argument queries are "AND"ed together. If you have more complex query requirements (for example, you need to include an ``OR`` @@ -400,31 +348,6 @@ See the `OR lookups examples page`_ for more examples. .. _OR lookups examples page: http://www.djangoproject.com/documentation/models/or_lookups/ -Ordering -======== - -The results are automatically ordered by the ordering tuple given by the -``ordering`` key in the model, but the ordering may be explicitly -provided by the ``order_by`` argument to a lookup:: - - Poll.objects.filter(pub_date__year=2005, - pub_date__month=1).order_by('-pub_date', 'question') - -The result set above will be ordered by ``pub_date`` descending, then -by ``question`` ascending. The negative sign in front of "-pub_date" indicates -descending order. Ascending order is implied. To order randomly, use "?", like -so:: - - Poll.objects.order_by=(['?']) - -To order by a field in a different table, add the other table's name and a dot, -like so:: - - Choice.objects.all().order_by=('Poll.pub_date', 'choice') - -There's no way to specify whether ordering should be case sensitive. With -respect to case-sensitivity, Django will order results however your database -backend normally orders them. Relationships (joins) ===================== @@ -489,16 +412,116 @@ return a list of instances instead of a single instance. So, if the relationshi between ``Poll`` and ``Choice`` was many-to-many, ``choice.get_poll_list()`` would return a list. -Relationships across applications ---------------------------------- +Specialist Query Sets +===================== -If a relation spans applications -- if ``Place`` was had a ManyToOne relation to -a ``geo.City`` object, for example -- the name of the other application will be -added to the method, i.e. ``place.get_geo_city()`` and -``city.get_places_place_list()``. +In addition to ``filter`` and ``exclude()``, Django provides a range of +Query Set refinement methods that modify the types of results returned by +the Query Set, or modify the way the SQL query is executed on the database. -Selecting related objects -------------------------- +order_by(\*fields) +------------------ + +The results returned by a Query Set are automatically ordered by the ordering +tuple given by the ``ordering`` meta key in the model. However, ordering may be +explicitly provided by using the ``order_by`` method:: + + Poll.objects.filter(pub_date__year=2005, + pub_date__month=1).order_by('-pub_date', 'question') + +The result set above will be ordered by ``pub_date`` descending, then +by ``question`` ascending. The negative sign in front of "-pub_date" indicates +descending order. Ascending order is implied. To order randomly, use "?", like +so:: + + Poll.objects.order_by=('?') + +To order by a field in a different table, add the other table's name and a dot, +like so:: + + Choice.objects.order_by=('Poll.pub_date', 'choice') + +There's no way to specify whether ordering should be case sensitive. With +respect to case-sensitivity, Django will order results however your database +backend normally orders them. + +distinct() +---------- + +By default, a Query Set will not eliminate duplicate rows. This will not +happen during simple queries; however, if your query spans relations, +or you are using a Values Query Set with a ``fields`` clause, it is possible +to get duplicated results when a Query Set is evaluated. + +``distinct()`` returns a new Query Set that eliminates duplicate rows from the +results returned by the Query Set. This is equivalent to a ``SELECT DISTINCT`` +SQL clause. + +values(\*fields) +---------------- + +Returns a Values Query Set - a Query Set that evaluates to a list of +dictionaries instead of model-instance objects. Each dictionary in the +list will represent an object matching the query, with the keys matching +the attribute names of the object. + +It accepts an optional parameter, ``fields``, which should be a list or tuple +of field names. If you don't specify ``fields``, each dictionary in the list +returned by ``get_values()`` will have a key and value for each field in the +database table. If you specify ``fields``, each dictionary will have only the +field keys/values for the fields you specify. For example:: + + >>> Poll.objects.values() + [{'id': 1, 'slug': 'whatsup', 'question': "What's up?", + 'pub_date': datetime.datetime(2005, 2, 20), + 'expire_date': datetime.datetime(2005, 3, 20)}, + {'id': 2, 'slug': 'name', 'question': "What's your name?", + 'pub_date': datetime.datetime(2005, 3, 20), + 'expire_date': datetime.datetime(2005, 4, 20)}] + >>> Poll.objects.values('id', 'slug') + [{'id': 1, 'slug': 'whatsup'}, {'id': 2, 'slug': 'name'}] + +A Values Query Set is useful when you know you're only going to need values +from a small number of the available fields and you won't need the +functionality of a model instance object. It's more efficient to select only +the fields you need to use. + +dates(field, kind, order='ASC') +------------------------------- + +Returns a Date Query Set - a Query Set that evaluates to a list of +``datetime.datetime`` objects representing all available dates of a +particular kind within the contents of the Query Set. + +``field`` should be the name of a ``DateField`` or ``DateTimeField`` of your +model. + +``kind`` should be either ``"year"``, ``"month"`` or ``"day"``. Each +``datetime.datetime`` object in the result list is "truncated" to the given +``type``. + + * ``"year"`` returns a list of all distinct year values for the field. + * ``"month"`` returns a list of all distinct year/month values for the field. + * ``"day"`` returns a list of all distinct year/month/day values for the field. + +``order``, which defaults to ``'ASC'``, should be either ``"ASC"`` or ``"DESC"``. +This specifies how to order the results. + +For example:: + + >>> Poll.objects.dates('pub_date', 'year') + [datetime.datetime(2005, 1, 1)] + >>> Poll.objects.dates('pub_date', 'month') + [datetime.datetime(2005, 2, 1), datetime.datetime(2005, 3, 1)] + >>> Poll.objects.dates('pub_date', 'day') + [datetime.datetime(2005, 2, 20), datetime.datetime(2005, 3, 20)] + >>> Poll.objects.dates('pub_date', 'day', order='DESC') + [datetime.datetime(2005, 3, 20), datetime.datetime(2005, 2, 20)] + >>> Poll.objects.filter(question__contains='name').dates('pub_date', 'day') + [datetime.datetime(2005, 3, 20)] + +select_related() +---------------- Relations are the bread and butter of databases, so there's an option to "follow" all relationships and pre-fill them in a simple cache so that later calls to @@ -508,9 +531,9 @@ queries, but it means that later use of relationships is much faster. For example, using the Poll and Choice models from above, if you do the following:: - c = Choice.objects.get(id=5, select_related=True) + c = Choice.objects.select_related().get(id=5) -Then subsequent calls to ``c.get_poll()`` won't hit the database. +Then subsequent calls to ``c.poll`` won't hit the database. Note that ``select_related`` follows foreign keys as far as possible. If you have the following models:: @@ -526,71 +549,67 @@ following models:: # ... choice = models.ForeignKey(Choice) -then a call to ``singlevotes.get_object(id=4, select_related=True)`` will +then a call to ``SingleVotes.objects.select_related().get(id=4)`` will cache the related choice *and* the related poll:: - >>> sv = singlevotes.get_object(id=4, select_related=True) - >>> c = sv.get_choice() # Doesn't hit the database. - >>> p = c.get_poll() # Doesn't hit the database. + >>> sv = SingleVotes.objects.select_related().get(id=4) + >>> c = sv.choice # Doesn't hit the database. + >>> p = c.poll # Doesn't hit the database. - >>> sv = singlevotes.get_object(id=4) # Note no "select_related". - >>> c = sv.get_choice() # Hits the database. - >>> p = c.get_poll() # Hits the database. + >>> sv = SingleVotes.objects.get(id=4) + >>> c = sv.choice # Hits the database. + >>> p = c.poll # Hits the database. -Extra lookup options -==================== +extra(params, select, where, tables) +------------------------------------ -There are a few other ways of more directly controlling the generated SQL -for the lookup. Note that by definition these extra lookups may not be -portable to different database engines (because you're explicitly writing -SQL code) and should be avoided if possible.: +Sometimes, the Django query syntax by itself isn't quite enough. To cater for these +edge cases, Django provides the ``extra()`` Query Set modifier - a mechanism +for injecting specific clauses into the SQL generated by a Query Set. +Note that by definition these extra lookups may not be portable to different +database engines (because you're explicitly writing SQL code) and should be +avoided if possible.: ``params`` ----------- - -All the extra-SQL params described below may use standard Python string -formatting codes to indicate parameters that the database engine will -automatically quote. The ``params`` argument can contain any extra -parameters to be substituted. + All the extra-SQL params described below may use standard Python string + formatting codes to indicate parameters that the database engine will + automatically quote. The ``params`` argument can contain any extra + parameters to be substituted. ``select`` ----------- + The ``select`` keyword allows you to select extra fields. This should be a + dictionary mapping attribute names to a SQL clause to use to calculate that + attribute. For example:: -The ``select`` keyword allows you to select extra fields. This should be a -dictionary mapping attribute names to a SQL clause to use to calculate that -attribute. For example:: + Poll.objects.extra( + select={ + 'choice_count': 'SELECT COUNT(*) FROM choices WHERE poll_id = polls.id' + } + ) - Poll.objects.extra( - select={ - 'choice_count': 'SELECT COUNT(*) FROM choices WHERE poll_id = polls.id' - } - ) - -Each of the resulting ``Poll`` objects will have an extra attribute, ``choice_count``, -an integer count of associated ``Choice`` objects. Note that the parenthesis required by -most database engines around sub-selects are not required in Django's ``select`` -clauses. + Each of the resulting ``Poll`` objects will have an extra attribute, ``choice_count``, + an integer count of associated ``Choice`` objects. Note that the parenthesis required by + most database engines around sub-selects are not required in Django's ``select`` + clauses. ``where`` / ``tables`` ----------------------- + If you need to explicitly pass extra ``WHERE`` clauses -- perhaps to perform + non-explicit joins -- use the ``where`` keyword. If you need to + join other tables into your query, you can pass their names to ``tables``. -If you need to explicitly pass extra ``WHERE`` clauses -- perhaps to perform -non-explicit joins -- use the ``where`` keyword. If you need to -join other tables into your query, you can pass their names to ``tables``. + ``where`` and ``tables`` both take a list of strings. All ``where`` parameters + are "AND"ed to any other search criteria. -``where`` and ``tables`` both take a list of strings. All ``where`` parameters -are "AND"ed to any other search criteria. + For example:: -For example:: + Poll.objects.filter( + question__startswith='Who').extra(where=['id IN (3, 4, 5, 20)']) - Poll.objects.filter( - question__startswith='Who').extra(where=['id IN (3, 4, 5, 20)']) + ...translates (roughly) into the following SQL:: -...translates (roughly) into the following SQL: - - SELECT * FROM polls_polls WHERE question LIKE 'Who%' AND id IN (3, 4, 5, 20); + SELECT * FROM polls_polls WHERE question LIKE 'Who%' AND id IN (3, 4, 5, 20); Changing objects ================ @@ -619,25 +638,26 @@ of objects then calling save() on them:: Calling ``save()`` on an object with a primary key whose value is ``None`` signifies to Django that the object is new and should be inserted. -Related objects (e.g. ``Choices``) are created using convenience functions:: +Related objects are created using the ``create()`` convenience function on +the descriptor Manager for relation:: - >>> p.add_choice(choice="Over easy", votes=0) - >>> p.add_choice(choice="Scrambled", votes=0) - >>> p.add_choice(choice="Fertilized", votes=0) - >>> p.add_choice(choice="Poached", votes=0) - >>> p.get_choice_count() + >>> p.choice_set.create(choice="Over easy", votes=0) + >>> p.choice_set.create(choice="Scrambled", votes=0) + >>> p.choice_set.create(choice="Fertilized", votes=0) + >>> p.choice_set.create(choice="Poached", votes=0) + >>> p.choice_set.count() 4 -Each of those ``add_choice`` methods is equivalent to (but much simpler than):: +Each of those ``create()`` methods is equivalent to (but much simpler than):: >>> c = Choice(poll_id=p.id, choice="Over easy", votes=0) >>> c.save() -Note that when using the `add_foo()`` methods, you do not give any value +Note that when using the `create()`` method, you do not give any value for the ``id`` field, nor do you give a value for the field that stores the relation (``poll_id`` in this case). -The ``add_FOO()`` method always returns the newly created object. +The ``create()`` method always returns the newly created object. Deleting objects ================ @@ -647,12 +667,21 @@ deletes the object and has no return value. Example:: >>> c.delete() -Objects can also be deleted in bulk using the same query parameters that are -used for get_object and other query methods. For example:: +Objects can also be deleted in bulk. Every Query Set has a ``delete()`` method +that will delete all members of the query set. For example:: - >>> Polls.objects.delete(pub_date__year=2005) + >>> Polls.objects.filter(pub_date__year=2005).delete() -would bulk delete all Polls with a year of 2005. +would bulk delete all Polls with a year of 2005. Note that ``delete()`` is the +only Query Set method that is not exposed on the Manager itself. + +This is a safety mechanism to prevent you from accidentally requesting +``Polls.objects.delete()``, and deleting *all* the polls. + +If you *actually* want to delete all the objects, then you have to explicitly +request a complete query set:: + + Polls.objects.all().delete() Comparing objects ================= diff --git a/docs/model-api.txt b/docs/model-api.txt index ab46b851ba..c982db4025 100644 --- a/docs/model-api.txt +++ b/docs/model-api.txt @@ -976,6 +976,11 @@ object, which takes the following parameters. All are optional. obviously, be some kind of text field, such as ``CharField`` or ``TextField``. +Managers +======== + +... Need to describe managers here + Model methods =============