Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use plain model.Manager, or suitable proxy, for model saving.
We can't use the default manager in Model.save_base(), since we need to retrieve existing objects which might be filtered out by that manager. We now always use a plain Manager instance at that point (or something that can replace it, such as a GeoManager), making all existing rows in the database visible to the saving code. The logic for detecting a "suitable replacement" plain base is the same as for related fields: if the use_for_related_fields is set on the manager subclass, we can use it. The general requirement here is that we want a base class that returns the appropriate QuerySet subclass, but does not restrict the rows returned. Fixed #8990, #9527. Refs #2698 (which is not fixed by this change, but it's the first part of a larger change to fix that bug.) git-svn-id: http://code.djangoproject.com/svn/django/trunk@10056 bcc190cf-cafb-0310-a4f2-bffc1f526a37
- Loading branch information
Showing
4 changed files
with
65 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
""" | ||
Regression tests for custom manager classes. | ||
""" | ||
|
||
from django.db import models | ||
|
||
class RestrictedManager(models.Manager): | ||
""" | ||
A manager that filters out non-public instances. | ||
""" | ||
def get_query_set(self): | ||
return super(RestrictedManager, self).get_query_set().filter(is_public=True) | ||
|
||
class RestrictedClass(models.Model): | ||
name = models.CharField(max_length=50) | ||
is_public = models.BooleanField(default=False) | ||
|
||
objects = RestrictedManager() | ||
plain_manager = models.Manager() | ||
|
||
def __unicode__(self): | ||
return self.name | ||
|
||
__test__ = {"tests": """ | ||
Even though the default manager filters out some records, we must still be able | ||
to save (particularly, save by updating existing records) those filtered | ||
instances. This is a regression test for #FIXME. | ||
>>> obj = RestrictedClass.objects.create(name="hidden") | ||
>>> obj.name = "still hidden" | ||
>>> obj.save() | ||
# If the hidden object wasn't seen during the save process, there would now be | ||
# two objects in the database. | ||
>>> RestrictedClass.plain_manager.count() | ||
1 | ||
""" | ||
} |