I need to create 3 different models that have some common properties and methods, but are separate in the DB. I couldn't find any examples of inheriting from another model without using the PolyModel base class.
Is it safe to do the following?
class BaseModel(db.Model):
common_prop = db.StringProperty()
#classmethod
def common_method(cls, a):
...
class SonModel1(BaseModel):
private_prop = db.StringProperty()
Related
I'm trying to create a reusable app where I define some abstract models, and some concrete versions of those models that the user can use if they don't want to inherit the models themselves. If the user does want to create their own subclasses then I don't want Django to create these concrete models.
This is the solution I have at the moment:
myapp/abstract.py
class AbstractModel1:
class Meta:
abstract = True
field1 = models.CharField(max_length=255)
class AbstractModel2:
class Meta:
abstract = True
field1 = models.CharField(max_length=255)
field2 = models.ForeignKey(getattr(settings, 'ABSTRACTMODEL1_OVERRIDE', 'myapp.ConcreteModel1'))
myapp/models.py
if not hasattr(settings, 'ABSTRACTMODEL1_OVERRIDE'):
class ConcreteModel1(AbstractModel1):
pass
if not hasattr(settings, 'ABSTRACTMODEL2_OVERRIDE'):
class ConcreteModel2(AbstractModel2):
pass
Then in the user's app, they can either use the concrete models as provided, or if not then they can create their own subclasses of the model like so:
userapp/models.py
class CustomModel1(AbstractModel1):
extrafield1 = models.CharField(max_length=255)
userapp/settings.py
ABSTRACTMODEL1_OVERRIDE = "userapp.CustomModel1"
Is this the best way to achieve this? Am I setting myself up for difficulties when trying to migrate changes in the subclassed models? What if the user wants to use the provided concrete classes first then migrate to a custom class?
Example situation as follows:
# models.py
class Form(models.Model):
name = models.CharField()
class A(models.Model):
form = models.ForeignKey(Form)
class B(A):
name = models.CharField()
# view.py
form = Form.objects.get(id=1)
form.a_set.all() # works
form.b_set.all() # doesn't work
I would like to access all the related B Objects via the parent class A foreign key but I can't seem to do this. And if I access them via A then I just get the generic parent class query set. Thank you.
When you inherit from a concrete model, there will be two tables (unlike inheriting from an abstract model) for Parent and Child models.
Django will implicitly create a OneToOneField from Child to Parent model named parent_ptr, thus:
B.objects.filter(a_ptr__form=form)
# B.objects.filter(a_ptr__form_id=1)
will give you the desired QuerySet.
I am attempting to create a model class that all models will inherit from when they are created (in Django). I want any model class, with any attributes to be able to inherit from this class and read from the appropriate database table.
I know I am going need to use **kwargs and .setattr() at some point but am unclear as to where I even start. I am also going to try to recreate .all(), .filter() and .get() with in that class that all other methods that inherit this class can access.
This is what I have so far:
import sqlite3
class Model:
def __init__(self):
pass
#classmethod
def all(self, **kwargs):
pass
#classmethod
def get(self):
pass
#classmethod
def filter(self):
pass
###don't touch the code for these
class Users(Model):
pass
class Stocks(Model):
pass
How can I go about the initialization of this class?
It looks like you're trying to insert an abstract base class for your models.
Basically, what you've got there is correct, except you're missing
from django.db.models import Model
class MyModelBase(Model):
class Meta:
abstract = True
# ... The fields and methods I want all my models to inherit.
Then rather than making your models inherit from django.db.models.Model, they should inherit from MyModelBase.
I would like to create a models.Model class that doesn't became part of the database but just an interface to other models (I want to avoid repeating code).
Something like that:
class Interface(models.Model):
a = models.IntegerField()
b = models.TextField()
class Foo(Interface):
c = models.IntegerField()
class Bar(Interface):
d = models.CharField(max_length='255')
So my database should have only Foo (with a,b,c collumns) and Bar (with a,b,d) but not the table Interface.
"Abstract base classes"
Abstract base classes are useful when you want to put some common information into a number of other models. You write your base class and put abstract=True in the Meta class. This model will then not be used to create any database table. Instead, when it is used as a base class for other models, its fields will be added to those of the child class.
You can define your classes like this:
from django.db import models
class CommonInfo(models.Model):
name = models.CharField(max_length=100)
age = models.PositiveIntegerField()
class Meta:
abstract = True
class Student(CommonInfo):
home_group = models.CharField(max_length=5)
I'm trying to emulate an inheritance model using django's generic relations. So far, this is what I've come up with:
class Base(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey()
... other stuff
class Meta:
unique_together = ("content_type", "object_id")
class SubClass1(models.Model):
... properties for this class
_base = generic.GenericRelation(Base)
#property
def base(self):
return self._base.all()[0]
From what you can see here (hopefully, at least), the SubClass1 should have a one-to-one relationship with Base, which is why I went through all the work of creating that _base field and then covering it with the base property. Having that generic relation will automagically wire up cascading deletes, which is what I want (and I have a post-delete signal that will wire up the delete from the other direction).
There could be any number of subclasses off of Base, and the thing that makes me feel gross is having to copy&paste the _base and its covering property. I've also got a custom object manager that goes with this, and potentially other things that essentially should all behave the same within each subclass of Base.
Is there a good way to go about encapsulating this common functionality so I don't have to copy&paste it for each sub class?
Why not have a BaseSubClass, and then inherit from that. So based on your example:
class BaseSubClass(models.Model):
_base = generic.GenericRelation(Base)
class Meta:
abstract = True
#property
def base(self):
return self._base.all()[0]
class SubClass1(BaseSubClass):
# fields