Skip to content

Feature proposal: override default manager for a model #747

@DrCuriosity

Description

@DrCuriosity

I'd like to explore the possibility of setting a specific manager (or possibly queryset?) for a tracked model, to override the default value.

If we can find a good approach, I may be able to submit to a PR for this.

Why?

I've run into an issue where the default managers on some of our models can disable certain records, and make it an explicit action to look at disabled records, while they are masked out of the default queryset for the majority of operations.

When updates are made on those objects (e.g. when re-enabling them), the comparisons recorded in the LogEntry essentially treat it as a new record.

This seems to happen because of the use of sender._default_manager.filter(pk=instance.pk).first() in the receivers.

Working around the problem for now?

I could go with audit_objects = [Model]AuditManager and set the model's default manager to that instead of using the standard objects = [Model]Manager.

This would solve the current problem, but that may also raise problems down the line for other system components that are expecting our standard default manager behaviours.

Possible fixes: add a setting in registry configuration?

Adding a "manager" key in AUDITLOG_INCLUDE_TRACKING_MODELS that can nominate a specific manager to use for a model.

A stricter implementation of this could check in the model's ._meta.managers_map to ensure that the value was an appropriate manager object:

AUDITLOG_INCLUDE_TRACKING_MODELS = (
    {
        "model": "<appname>.<model>",
        "manager": "audit_objects",
        ...
    },
)

Alternately, a looser model could support a queryset callable:

AUDITLOG_INCLUDE_TRACKING_MODELS = (
    {
        "model": "<appname>.<model>",
        "queryset": "<appname>.<model>.get_full_queryset",
        ...
    },
)

In each case, the default behaviour would continue to use the existing sender._default_manager for filtering.

Questions

  • Are there any problems with doing this that I might have missed?
  • Is there any preference for stricter nomination of model managers vs. the looser queryset callable approach?

Thanks for your consideration :-)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions