Django parent model and subclassing again - django

say i have
class Visualizer(models.Model):
owner = models.ForeignKey(settings.AUTH_USER_MODEL, editable=False, null=True, blank=True )
title = models.CharField(max_length=255)
description = models.TextField()
feed = models.ForeignKey(Feed)
channels = models.ManyToManyField(Channel)
And in my project there can be any number of visualizers that can have extra attributes...
like one visualizer can have a 'base_color' extra attribute, and for another 'change_by_type' extra attribute... etc.. as:
#there can be 5 to 10 visualizer types VisualizerA, VisualizerB ...
class VisualizerA(models.Model):
#base visualizer attributes
base_color = models.CharField()
For now i am doing by adding an attributes text field to the base Visualizer model not adding any sub classes and keep the properties as json string. But i am having hard times with the forms... Is there a better way?
Is subclassing a choice? (But there can be 5 or 10 types of visualizer )
i need a way of doing this right...

Depending or your requirements "Django dynamic model fields" may be the solution. See post
Django dynamic model fields
In terms of of inheritance you can have Model inheritance with specialized Forms
Here is "Advanced Django Forms Usage" http://www.slideshare.net/pydanny/advanced-django-forms-usage
and/or Forms inheritance with common Model
see post http://pydanny.com/overloading-form-fields.html

Subclassing is imo best solution, in database You will have 1 table for all Visualizers with all fields from base class and 1 table for each child class with id column that will have same values as in base class and columns from child class fields. It's one to one relation under the hood, but when You save new instance of child model, django will automatically make corresponding field in base model.
More here: Django model interhitance

Related

django-rest-framework multiple serializers in the same request

I know there's something similar answered here, but my question is not the same. I'm using multi-table inheritance to model 2 different types of entities, and both of them can create posts. My problem is when trying to create a view that shows all the posts together.
So I have my Entity model, and then my ETypeA and ETypeB models, which look like this:
class Entity(models.Model):
pass
class ETypeA(Entity):
# Here are some attributes
pass
class ETypeB(Entity):
# Here are some attributes
pass
As you can see, the Entity model it's just for having a common primary key between ETypeA and ETypeB. The reason for this is to have just one common Post model, like this:
class Post(models.Model):
transmitter = models.ForeignKey(Entity, on_delete=models.CASCADE)
text = models.CharField(max_length=500, null=False, blank=False)
The problem now is that when I create a view to show the posts I get only the id of the transmitter but I need the whole information. The way of doing it in SQL should be joining the results with ETypeA, then with ETypeB and make a union between the results (keeping some fields as nulls). Then I should be capable of sorting them by date. How can I do that with DRF views and serializers?

django - query mutliple models for the same field in each in 1 query

Say I have 3 models (Blog, News, Photos) and i want to get the latest 3 pieces of content regardless of which model they belong to.
With (psuedo) sql I could do something like:
SELECT *
FROM blog, news, photo,
WHERE is_published=True
ORDER by publication_date
LIMIT 3
I don't really want to use to use raw sql in Django as i want a query set returned, so is there a way I can make this type of query with Django?
Thanks,
If the 3 models are similar in some way (as they appear to be), the way I would probably do it is by creating a base model and then have the 3 other models inherit from that model.
class Publishable(models.Model):
is_published = models.BooleanField(default=False)
publication_date = models.DatetimeField()
... other fields ...
class Blog(Publishable):
...extra fields...
class News(Publishable):
...extra fields...
class Photos(Publishable):
...extra fields...
Then later on, you can do:
Publishable.objects.order_by('-publication_date')[:3]
If you still need the "type" associated with the retrieved models, check out the Inheritance Manager
You'll probably want to read about the pros and cons about Model Inheritance as well.

Choosing the right user inheritance method for django 1.5

I have a situation where I need to subclass a custom user model for a django 1.5 project (related question/background here: Subclassing AbstractUser in Django for two types of users )
I need an abstract user class SchoolPerson and a number of subclasses (Student, Teacher, etc) based on this. I think I've resolved that I need to have the user model in a separate DB table to the subclasses as other apps rely on AUTH_USER_MODEL, of which there can only be one.
So the way I see it, I have to options to do this: add one-to-one to the standard user model in my abstract SchoolPerson class:
class SchoolPerson(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
...
class Meta:
abstract = True
class Student(SchoolPerson):
year_level = models.CharField(max_length=3)
...
class Teacher(SchoolPerson):
govt_id = models.CharField(max_length=10)
...
Or I can make my SchoolPerson model inherit AbstractUser, but keep this class non-abstract:
class SchoolPerson(AbstractUser):
...
#no Meta abstract here
class Student(SchoolPerson):
year_level = models.CharField(max_length=3)
...
class Teacher(SchoolPerson):
govt_id = models.CharField(max_length=10)
...
Are there any advantages to one of these over the other?
I haven't tested this but what I expect is for your first suggestion to create two db tables:
one for Student and one for Teacher each with a foreign key to the AUTH_USER_MODEL.
For the second one I expect Django to create three db tables:
One for the SchoolPerson(which will be exact as the default Users table with the additional fields) and two for Student and Teacher with foreign keys to SchoolPerson.
So I think the answer depends on your requirements.

Django: Foreign key relation depending on choice

In Django, is there a way to create the following dynamic relationship between models?
class ClothingMale(models.Model):
# male specific fields
class ClothingFemale(models.Model):
# female specific fields
class Person(models.Model):
gender = models.IntegerField(max_length=2, choices=GENDER_CHOICES, blank=True)
clothes = models.ForeignKey(???)
I am using a ModelForm for Person. The clothes fields inside the form should change dynamically depending on which gender was selected. I am aware of GenericForeignKeys but I was wondering if there is better way to solve this?
IMHO it's a question of DB design; I would go for a PersonClothing superclass and subclass it with MalePersonClothing and FemalePersonClothing. The PersonClothing superclass would be a Django abstract base class; a specific class useful when you want to put some common information into a number of other models.
To do it just specify the following option in your model's meta:
class Meta:
abstract = True
One option is to use GenericForeignKey. This of course has int's down-sides, for exampl you cannot filter() on GenericForeignKey
Another option is to use model inheritance, which also has quite a few gotchas.

Non-model field in Django model

I would like to have a model in Django that has multiple pictures associated with it. I'm evaluating possible options.
One picture for one model is easily done with the models.ImageField(...).
However, I would like a array (or set) of pictures. It can be just paths, not necessarily ImageField objects.
The problem is, how do I create that field in a Django model? I am assuming I will need to create a field that is not part of models.WhateverField. Is that possible? Can I define a non-model field, such as:
class MyModel:
name = models.CharField(max_length=10)
picture_list = []
and then do:
def sample_add_picture_view(request):
picture = "sample.jpg"
model = MyModel.objects.get(id=sample_id)
model.picture_list.append(picture)
model.save()
return HttpResponseRedirect('index.html')
Could this be done? If not, what could be a better solution? Thank you !
You need to create two separate models and link them with a ForeignKey field, like so:
class Item(models.Model):
name = models.CharField(max_length=255)
class ItemImage(models.Model):
image = models.ImageField(upload_to="item_images")
item = models.ForeignKey('Item', related_name="images")
It is possible to make a custom field to store multiple items, but it's a really bad idea. You would have to serialise an array into the database, making maintenance very difficult. Using a separate model means you can store extra information such as upload times, image captions etc with little extra effort.