class BaseModel(models.Model): # base class should subclass 'django.db.models.Model'
creation_date = models.DateTimeField(..) # define the common field1
class Meta:
abstract=True # Set this model as Abstract
Inherit this Base class in models
After creating the abstract base class BaseModel, I inherited this class in my models.
class MyModel1(BaseModel): # inherit the base model class
# define other non-common fields here
...
After creating an object of class 'MyModel1', I want the 'creation_date' field to be shown in admin interface.
So that I can see the datetime when an object of class 'MyModel1' is created.
Solution:
class MyModel1Admin(admin.ModelAdmin):
readonly_fields= ['creation_date',]
admin.site.register(MyModel1,MyModel1Admin)
Related
For example, if I have 3 models that look like this:
class CallLog(models.Model):
lead_id = models.BigIntegerField("Lead ID")
# other fields
class EmailLog(models.Model):
lead_id = models.BigIntegerField("Lead ID")
# other fields
class TextLog(models.Model):
lead_id = models.BigIntegerField("Lead ID")
# other fields
Do I add lead_id to each model individually or is there a way to only type it once?
Yes, you can define an abstract base class [Django-doc]:
class LeadId(models.Model):
lead_id = models.BigIntegerField("Lead ID")
class Meta:
abstract = True
and then inherit this in the other models:
class CallLog(LeadId, models.Model):
# other fields…
class EmailLog(LeadId, models.Model):
# other fields…
class TextLog(LeadId, models.Model):
# other fields…
You can define multiple such abstract base classes, and use multiple inheritance such that models inherit from multiple of such classes.
I.e. we have SomeSeries with several SomeDecors, where ForeignKey of SomeDecor points to SomeSeries. I want both to be abstract and later instantiate several pairs of it (with it's own tables in db). Is it possible?
I.e.
class SomeSeries(models.Model):
class Meta:
abstract = True
vendor = models.ForeignKey(Vendor)
name = models.CharField(max_length=255, default='')
def __unicode__(self):
return "{} {}".format(self.vendor, self.name)
class SomeDecor(WithFileFields):
class Meta:
abstract = True
series = models.ForeignKey(SomeSeries) # some magic here to make ForeignKey to abstract model
texture = models.ImageField()
# -------------------------------------------
class PlinthSeries(SomeSeries): pass
class PlinthDecor(SomeDecor): pass
# Some magic to make PlinthDecor.series points to PlinthSeries
EDIT
Actually I don't want complicity of polymorphic relations, I want pure abstract models just to save typing (what abstract models are initially for). Suppose in my case the simplest way is to exclude ForeignKey from base model and type it only in all inherited models:
class SomeSeries(models.Model):
class Meta:
abstract = True
#...
class SomeDecor(WithFileFields):
class Meta:
abstract = True
series = None #?
#..
texture = models.ImageField()
def do_anything_with_series(self): pass
class PlinthSeries(SomeSeries): pass
class PlinthDecor(SomeDecor): pass
series = models.ForeignKey(PlinthSeries)
You can't create ForeignKey referencing abstract model. It's, even, doesn't make any sense, because ForeignKey translates into Foreign Key Constraint which have to reference existing table.
As a workaround, you can create GenericForeignKey field.
You can not do it because if you create two class inherit from your abstract class to what class your foreignkey should do? for first or for second?
So you need to create GenericForeignKey or not do any field and only after create model inherits from your abstract model add your foreign key.
In my Django 1.11 app, I have an abstract model class AbstractModel, from which I subclass concrete models FooModel and BarModel. There are also concrete models FooValue and BarValue defined. From within AbstractModel, I want to define a one to one field to the corresponding Value model.
class AbstractModel(models.model)
value = models.OneToOneField('corresponding Value class name', ...)
class Meta:
abstract = True
class FooModel(AbstractModel):
pass
class BarModel(AbstractModel):
pass
class FooValue(models.model):
pass
class BarValue(models.model):
pass
How do I get corresponding 'XXXValue' class name depending on which concrete XXXModel class is in scope?
To do this, I need the current concrete model class name _my_class_name in the class definition (which seems hard to impossible).
I'd like to define a new _id autofield in one of the derived classes.
Simply specifying _id field for the derived class results in an error "
A model can't have more than one AutoField."
class Base(models.Model):
class Meta:
abstract = True
class Derived(Base):
_id = models.AutoField(primary_key=True)
Can you specify when its raise an error? I have same configuration in my project which is working fine.
I'm trying to create a Django ORM mapping that's compatible with an existing data model, so I'm trying to work with an existing set of table and column names.
I've got a multi-table inheritance situation where a class InformationObject derives from class Object. I'd like to let Django handle this the usual way:
class Object(models.Model):
class Meta:
db_table = "object"
class InformationObject(Object):
class Meta:
db_table = "information_object"
In this case Django would automatically create a one-to-one field on the inheriting model called object_ptr_id. However, on the schema I'm constrained to use, the reference to the Object is simply called "id". So:
Is there a way to somehow specify the name of the column Django auto-magically uses for multi-table inheritance?
The alternative, which I'll have to use otherwise, is to use an explicit one-to-one field, but then I won't be able to inherit non-database methods from the Object model:
class Object(models.Model):
class Meta:
db_table = "object"
class InformationObject(models.Model):
class Meta:
db_table = "information_object"
id = models.OneToOneField(Object, primary_key=True, db_column="id")
Any ideas? Maybe I could create a common base class for both of them and put non-db methods there...?
From the django docs (development version):
As mentioned, Django will automatically create a OneToOneField linking your child class back any non-abstract parent models. If you want to control the name of the attribute linking back to the parent, you can create your own OneToOneField and set parent_link=True to indicate that your field is the link back to the parent class.
As mentioned by #fusion quoting from the docs, you will have to create a OneToOneField if you want to specify the column, while using model inheritance. The inherited fields will be available in the child class in both self scope AND the one-to-one field.
class Object(models.Model):
class Meta:
db_table = "object"
column_1 = models.CharField()
class InformationObject(Object):
class Meta:
db_table = "information_object"
# arbitrary property name (parent_link)
parent_link = models.OneToOneField(Object, primary_key=True, db_column="id", parent_link=True)
In this example:
>>> inf_obj = InformationObject.objects.get(pk=1)
>>> print inf_obj.column_1 == inf_obj.parent_link.column_1
True