views:

137

answers:

2
class Account(models.Model):
        identifier = models.CharField(max_length=5)
        objects = MyCustomManager()

        class Meta:
            abstract = True

class Customer(Account):
        name = models.CharField(max_length=255)

If I have a lot of models, and I want to save time from having to put foreignkeys everywhere, is this right? Or, am I thinking of this all wrong?

+1  A: 

In this case you'll have 1 table for customer with account ID and if you'll add Worker he'll have his own table with account ID.

I think you probably want to have single table with accounts and attached objects customers, workers etc? This way you'll never mix-up your accounts.

Dmitry Shevchenko
+1  A: 

It depends in which direction the foreign keys go. You cannot have a foreign key to an abstract class.

Maybe it is Generic Relations what is interesting for you or foreign keys in abstract model classes.

Although notice that inheritance is always a is-a relationship while a normal foreign key usage implies a has-a relationship.

In your example, Customer should not inherit from Account as a customer has an account.

An inheritance example would be a Place which is either a Restaurant or a Cinema etc.

Edit after comment:

Well, there is a own section for this in the documentation:

Class inheritance and model managers aren't quite a perfect match for each other. Managers are often specific to the classes they are defined on and inheriting them in subclasses isn't necessarily a good idea. Also, because the first manager declared is the default manager, it is important to allow that to be controlled. So here's how Django handles custom managers and model inheritance:

...

  • Managers from abstract base classes are always inherited by the child class, using Python's normal name resolution order (names on the child class override all others; then come names on the first parent class, and so on). Abstract base classes are designed to capture information and behavior that is common to their child classes. Defining common managers is an appropriate part of this common information.
  • The default manager on a class is either the first manager declared on the class, if that exists, or the default manager of the first abstract base class in the parent hierarchy, if that exists. If no default manager is explicitly declared, Django's normal default manager is used.

I would only do if the inherited classes belong somehow to the same scope.
If you really a so many classes that it matters to add one line to these classes then you probably have not a good DB or application design.

And try not to put everything in one manager just to be able to use only one manager in a lot classes.

Felix Kling
What if I create an abstract class called `CustomManagerModel(models.Model)` and subclass that (so not for record purposes but so that it will use a manager that I want most classes to use).
orokusaki
yes you can subclass managers http://docs.djangoproject.com/en/dev/topics/db/managers/#custom-managers-and-model-inheritance
Dmitry Shevchenko
@dmishe: Just to clarify, it is inheriting managers, not subclassing (which is something differrent).
Felix Kling
@both Thanks guys, but I meant can I subclass a model that has a customer manager just for purposes of sharing it's manager (but without the "Is A" relationship that's involved with an Abstract class normally?
orokusaki
You have to read my answer better: "Abstract base classes are designed to capture information and behavior that is common to their child classes. Defining common managers is an appropriate part of this common information." This `is-a`, `has-a` is only a logical view on your models which should help you to structure your models.
Felix Kling