Opened 18 years ago
Closed 17 years ago
#3416 closed (fixed)
Model API documentation section 'Modifying initial Manager QuerySets' misleads about Admin behaviour
Reported by: | Alex Dedul | Owned by: | nobody |
---|---|---|---|
Component: | contrib.admin | Version: | dev |
Severity: | Keywords: | ||
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
It says:
If you use custom Manager objects, take note that the first Manager Django encounters (in order by which they're defined in the model) has a special status. Django interprets the first Manager defined in a class as the "default" Manager. Certain operations -- such as Django's admin site -- use the default Manager to obtain lists of objects, so it's generally a good idea for the first Manager to be relatively unfiltered.
But if you have your custom manager in a model even called 'objects' admin anyway will display all records from model regardless specified custom manager. The only way i found to tell admin to use custom manager is to use 'manager' attribute in inner Admin class in a model. So i guess reference to admin should be removed from here for now and 'manager' attribute of inner Admin class documented instead.
Change History (6)
comment:1 by , 18 years ago
comment:2 by , 18 years ago
I'm not trying to use custom manager directly in the code, but to tell admin app to use it(to prefilter records in change list). And whatever i call custom manager in a model 'objects' or 'test_manager' or something else it has no effect on admin's change list.
One more thing - tried with custom manager to see values of foreign key on a change form and here it works correctly displaying records from custom manager and not using default one with all records. So it seems it boils down to
django.db.models.AdminOptions.__init__()
and to this line:
self.manager = manager or Manager()
where manager is an attribute(undocumented) you can set on inner Admin class and Manager() is a default manager with all records.
So as for me its worth mentioning in docs about this hidden 'manager' attribute and say that model's custom managers is not used in admin's change lists(if we reference admin app in that 'Modifying initial Manager QuerySets' section).
comment:3 by , 18 years ago
I think it should work without using the "hidden manager attribute". Can you please post your model and the manager?
comment:4 by , 18 years ago
Here we go. Test case 1:
class KnowledgeBaseCategoryManager(models.Manager): def get_query_set(self): return super(KnowledgeBaseCategoryManager, self).get_query_set().\ filter(name='test') class KnowledgeBaseCategory(models.Model): name = models.CharField(maxlength=100, unique=True) class Meta: verbose_name_plural = 'Knowledge Base Categories' ordering = ('name', ) class Admin: search_fields = ('name',) manager = KnowledgeBaseCategoryManager() def __str__(self): return self.name >>> KnowledgeBaseCategory.objects.all() [<KnowledgeBaseCategory: test>, <KnowledgeBaseCategory: test2>]
KnowledgeBaseCategory has 2 records with name 'test' and 'test2', but in admin's change list there is only one record with name 'test' because of manager attribute of inner Admin class.
Test case 2:
# KnowledgeBaseCategoryManager is the same class KnowledgeBaseCategory(models.Model): name = models.CharField(maxlength=100, unique=True) test_manager = KnowledgeBaseCategoryManager() class Meta: verbose_name_plural = 'Knowledge Base Categories' ordering = ('name', ) class Admin: search_fields = ('name',) def __str__(self): return self.name >>> KnowledgeBaseCategory.test_manager.all() [<KnowledgeBaseCategory: test>]
Here is custom test_manager returns only 1 record 'test' as expected, but in admin's change list both 'test' and 'test2' records are displayed.
comment:5 by , 18 years ago
Component: | Documentation → Admin interface |
---|---|
Owner: | changed from | to
Triage Stage: | Unreviewed → Accepted |
Thanks! I see this as a bug in the admin. I made these observations with your second testcase:
- As you described, the admin shows both objects
- When I click on 'test2', I get a 404.
- In the shell, there is no
KnowledgeBaseCategory.objects
manager at all - In the shell, I see that
models.KnowledgeBaseCategory._meta.admin.manager
is the generic<django.db.models.manager.Manager object at 0xb759c20c>
I suppose that something does not pick up that _meta.admin.manager should be set to the custom manager.
comment:6 by , 17 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
This has been fixed in newforms-admin, where _meta.admin.manager
no longer exists as of [4342].
Now--did you call the model 'objects' or the custom manager? If the latter, does the situation change if you rename it from "objects" to something else?