5

I want to override related manager for a class.

I have a Company model. It has state column which can be in ACTIVE, INACTIVE, SUSPENDED. I am adding 2 new states called SALES, CLOSED.

Since its legacy model, just adding state can be devastating(there are very many places in code which doesn't filter by state).

So, to avoid inadvertent changes elsewhere, I decided to hide our new states for all other apps/elsewhere unless required otherwise (I'll whitelist only for our app/models)

I've overridden object manager in company.

class CompanyManager(models.Manager):

    def get_queryset(self):
        return super(CompanyRelatedManager, self).get_queryset().exclude(state__in=['SALES', 'CLOSED'])

class Company(models.Model):
    _default_manager = models.Manager()
    objects = CompanyManager()
    allObjects = models.Manager()

    name = models.TextField()
    ...
    salesContact = models.ForeignKey(Contact)

The problem is that Company.objects.filter(blah=blah) filters out new states. But something like salesContact.companies.all() doesn't.

In [9]: salesContact.companies
Out[9]: <django.db.models.fields.related.RelatedManager at 0x12157a990>

My question is how to override the related manager of the salesContact = models.ForeignKey(Contact) and the likes so that I can modify the default queryset to exclude my new state.

And, I can't override the default manager, since overriding default manager also implies that I am overriding the db_manager which results in un-intended consequence (db tries to insert instead of update, whole other story).

Mohan
  • 1,850
  • 1
  • 19
  • 42
  • 1
    https://stackoverflow.com/questions/10547583/override-djangos-relatedmanager-for-model/ doesn't answer my question since the answer there suggested an alternative approach specific to that problem. – Mohan Jan 10 '17 at 07:06
  • I am working on it. Unfortunately I am @ django1.7, so trying your soln in a virtual env. – Mohan Jan 11 '17 at 00:16
  • sorry missed the part about this being on django 1.7. But I think you should upgrade because 1.7 is no longer supported. Migrations feature alone would make the upgrade totally worth your while. – e4c5 Jan 11 '17 at 00:30
  • The problem with django is that companies fork and keep on adding to the fork without actually adding to django. Yes, we are working on untangling fork and upgrade – Mohan Jan 11 '17 at 00:32
  • Yes that's a bit of an issue. That's why other companies build pluggable apps or subclass existing django classes. – e4c5 Jan 11 '17 at 00:33
  • Is this sorted out now? – e4c5 Jan 17 '17 at 23:56
  • Since I am @ django 1.7, it gives me no way to customize related manager. However, I managed to write my own extension of foreign key which allows me to specify custom function which can return queryset. I'll consolidate what I've did and will post here. – Mohan Jan 18 '17 at 02:31

0 Answers0