should I use abstract model in this situation? - django

I'm wondering what is the best way to represent the models, because there are some fields in common and others that change according to the category.
Example: Common fields: (title, author, content, photo, references)
Category and its specific fields:
Biography (birth data, death data, occupation)
Commemorative date (data, description)
Music (artist, album, year, musical style)
The best would be to create a generic model with common fields and others inherit from it (abstract models)?
Create a model for each category, ie repeating the common fields?
Create a single model with the common fields and have a category field that when selected would display the category-specific fields in django-admin? In that case, I suppose it would be done with jquery? Any references? There is nothing the material has on this on the internet.
Note: All user interaction to register is in django-admin.

From the docs:
Often, you will just want to use the parent class to hold information that you don’t want to have to type out for each child
model. This class isn’t going to ever be used in isolation, so
Abstract base classes are what you’re after.
If you’re subclassing an existing model (perhaps something from another application entirely) and want each model to have its own
database table, Multi-table inheritance is the way to go.
So if you don't want the parent class to have it's own table, abstract model is the way to go.

Related

django multi-table inheritance, access method from child from instance of parent

I am using Multi-Table inheritance (aka Concrete Inheritance), where I have a non-abstract model + DB Table called Clients, which is concerned with common details concerning all the clients.
But a client can be an Individual, Partnership or Company, for which I have created inheriting models and tables. An Individual has first name + last name, and company has other specific particulars, etc.
I want to be able to access the names of clients (derived from the columns from the child tables) when I want a list of all clients.
After lot of searching, I found that this tutorial, works successfully.
Basically, it involves inserting a column on the Client table, which will store the name of the Child model. Then using that name, the appropriate child model is identified and appropriate child method is accessed.
But it seems to be a slightly cumbersome way to implement polymorphism in Multi-Table inheritance.
I want to know whether since 2012, Django has introduced any better way to deal with the issue, or is this still the only way?
Please let me know if my code sample is required, but the link provided has a beautiful example already.
There is django-model-utils application with Inheritance Manager. It will cast automatically your parent class to children instances. Example from docs:
from model_utils.managers import InheritanceManager
class Place(models.Model):
# ...
objects = InheritanceManager()
class Restaurant(Place):
# ...
class Bar(Place):
# ...
nearby_places = Place.objects.filter(location='here').select_subclasses()
for place in nearby_places:
# "place" will automatically be an instance of Place, Restaurant, or Bar
Also check this question for generic solution with ContentType.
And also check awesome article by Jeff Elmore about this topic. Quite old, but still great.

Django dynamic models

I'm pretty new to Django and Python. I'm trying to create some "category-dependent" models.
I have a Product model and i want to have category-dependent atributes. Example:
If i select "Permanent Dyes" in the category of my product i want to have specific atributes for my user to fill.
I don't want to create different models for every type of product i'm going to manage.
Is there any workaround to do this and keep using the django-admin?
Thanks in advance!
Model inheritance seems like it would help in this situation. Using it, you can have an abstract Product base class and then use Meta to add different product-dependent characteristics you need. It may require different models, but you would only need to add the attributes you needed, like below
class Product(models.Model):
....
class ProductA(Product):
class Meta:
....
This will allow you to have general properties in the Product class, such as price, etc., but use the subclass as a way to distinguish between different products.
Hope that helped in some way!

Django - how to duplicate all fields definitions from one model to another without inheritance

I need to define a extact copy of existing model with it's own table and all columns without Django inheritance mechanism. Otherwise it uses OneToOne relation and keeps all duplicated fields in parent table, that I definetly don't need. I just want to avoid repeating model fields and method definitions for my second model.
Any suggestions?
One way would be to create abstract base model with common attributes. Then create one model corresponding to parent model in current app.
Create another model for the duplicate model with same base class (and some other fields).
Not elegant though!
Did you look at Mixins?
With them you can mixin the fields of a class to your Model class and still inherit form a regular Base class. And you can mixin fileds from different classes and thus maybe make a good structure.
http://eflorenzano.com/blog/2008/05/17/exploring-mixins-django-model-inheritance/

Django Model field with multiple types?

I have the following (simplified) models:
class Structure(models.Model):
name=models.CharField(max_length=100, unique=True)
class Unit(models.Model):
name=models.CharField(max_length=100, unique=True)
Each model, also has a builtFrom field, which shows what the item is built from, for example:
class Unit(models.Model):
name=models.CharField(max_length=100, unique=True)
builtFrom=models.ForeignKey(Structure)
However, builtFrom can be populated from either a Unit type, or a Structure type. Is there an easy way to represent this in my models?
The only thing I can think of is to have a separate model, like so:
class BuiltFromItem(models.Model):
structure=models.ForeignKey(Structure)
unit=models.ForeignKey(Structure)
class Unit(models.Model):
name=models.CharField(max_length=100, unique=True)
builtFrom=models.ForeignKey(BuiltFromItem)
And then have one of the BuiltFromItem fields just be null. Then, when I need the data, figure out whether it is a structure or unit that it is built from. Is there a better solution for this?
You want what the Django docs refer to as a "generic relation". Support for them is built into Django.
Generic relation is probably the best approach, yet it can be a little problematic, if you're planning to manage such models via admin panel. You would then have to add a ModelInline to the models, that generic relation is pointing to, but as far as I know (correct me if I'm wrong), there's no convenient way of picking related object from the other side (from model, where relation is defined), other than choosing model class and manually typing instance primary key.
Picking the best solution actually depends on structure of your models and on what they have in common. Another idea I have, is to use Multi-table inheritance, by defining some BasicObject that is a parent object to Structure and Unit models:
class BasicObject(models.Model):
name=models.CharField(max_length=100, unique=True)
#other common data
builtFrom=models.ForeignKey('BasicObject')
class Structure(BasicObject):
#data specific to Structure
class Unit(BasicObject):
#data specific to Unit
Now all Structure and Unit object will also be BasicObject instances, and you will be able to populate builtFrom field with proper BasicObject instance. It makes queries more expensive, because data is divided into two diffrent tables, so you should consider if this approach is beneficial in your case.

django user relationship

Using django, say I have model classes A and B, representing different types of Companies. Each Company may have multiple Users associated with it. Obviously I'd like to use django's User model, to get the login, etc. goodness. How would I go about doing that? Would I add a UserProfile that has two foreign keys, one to A and one to B (and the one that isn't null points to the company that the User works for)? Or is there another way?
thanks!
Use inheritance: define a superclass for Company, with the common fields, and then inherit that class and add the stuff ClassACompany and ClassBCompany need.
This way the UserProfile can have a foreign key to Company. If you need to get from the company to the specific type of company, you can do that as described in the docs.
why dont you just have one class for Company? that'll make your system much, much simpler.
you can then have specific fields inside Company that will let you determine whether it's of type A or B (what's the difference anyway?)
If you really must have different fields inside CompanyA and CompanyB then you can have them both derive from a common Company class which your ForeignKey will point to.
You would need to reference the Company model, and if need be, subclass Company with CompanyA and CompanyB. For simplicity, your Company class could have a type attribute with possible A and B values, then you could avoid subclassing.