How to use base classes in Django
<p>I'm trying to alter an app I've created so that it is reusable. It's based around a single model which sites using the app will subclass. As it stands, my non-reusable version has the following kind of structure:</p>

<pre><code># models.py
class Document(models.Model):
     contents = models.TextField()
     date = models.DateTimeField()

# views.py
from .models import SiteModel
# ...
class MyView(ListView):
    def some_method(self, list_of_pks):
        model_vals = Document.objects.filter(pk__in = list_of_pks).values()

def perform_action(request):
    obj_pk = request.POST.get('obj_pk')
    obj = Document.objects.filter(pk = obj_pk)

    MySignal.send(sender=Document, instance = obj)

#etc, etc
</code></pre>

<p>This works well enough. But my use case calls for different types of <code>Document</code>, one per site, that will have additional fields that aren't known in advance. Based on reading the documentation on <a href="https://docs.djangoproject.com/en/1.10/topics/db/models/#abstract-base-classes" rel="nofollow">abstract base classes</a>, I thought the a reasonable solution would look like:</p>

<pre><code># models.py for the app 
class BaseDocument(models.Model):
    contents = models.TextField()

    class Meta:
        abstract = True

# models.py for a hypothetical site using the app
class SiteDocument(myapp.BaseDocument):
    date = models.DateTimeField()
    # other site-specific fields
</code></pre>

<p>What I don't understand is how to then reference the model in the app's <code>views.py</code>, <code>forms.py</code>, etc. I know <code>BaseDocument.objects.all()</code>, for example, won't return anything since it isn't connected to a database. Conversely, I can't have <code>Document.objects.all()</code> because <code>Document</code> hasn't been created yet and is specific to each site. Is an abstract base class not the correct solution, and if so, what is?</p>

<p><strong>Edit:</strong></p>

<p>It looks like using a <code>OneToOneField</code> may be best suited to my use case, although it looks like that precludes inheriting methods from the superclass and that <code>BaseDocument.objects.all()</code> won't list out all its children.</p>

<p>Alternatively, I was wondering if I could just add a <code>get_document_model()</code> method to my abstract base class, in the style of <a href="https://docs.djangoproject.com/en/1.8/_modules/django/contrib/auth/#get_user_model" rel="nofollow"><code>get_user_model()</code></a>?</p>

<p>You can't query your abstract classes directly like that since they won't have managers, only the inherited classes. If you really must do inheritance, you can use a concrete base model and inherit from that at the cost of a join on every query.</p>

<p>Think long and hard about whether this is truly necessary, or if you can represent your data in a more generic way. Models make inheritance seem easy, but they're not magic. There are very real performance and complexity considerations.</p>

<p>It might be as easy as adding a <code>type</code> field to your model</p>

<pre><code>class Document(models.Model):
    DOCUMENT_TYPES = ['site', 'another', 'whatever']

    document_type = models.CharField(choices=DOCUMENT_TYPES)
    ...
</code></pre>

<p>For more information about abstract vs concrete classes and querying, visit <a href="http://stackoverflow.com/questions/3797982/how-to-query-abstract-class-based-objects-in-django">How to query abstract-class-based objects in Django?</a></p>

python django django-models