Best way to implement models with many overlapping fields in Django? - django

I need to implement the following logic: there is a big model Base with many fields and several smaller models sharing some field subsets with it and with each other. For example, let's say that Base has fields a, b, c, d, e and f; model A has fields a, b, g; model B has fields b, c, d, g; model C has fields d, e, f, g.
Trying to do proper inheritance from abstract models will very quickly lead to a mess, but making manual copies of fields also seems suboptimal, since every field from the main model is present in the smaller ones and so will have to be listed twice. What's a good way to approach this?

You need to inherit from Base and make it to be abstract .
And then override fields that you don't need with None.
Django documentation mentions this here .
Fields inherited from abstract base classes can be overridden with another field or value, or be removed with None.

Related

Django filtering on foreign key properties, difference between explicit and implicit foreign key property naming

Suppose I have two models -
class A(models.Model):
a_id=models.CharField(max_length=255,primary_key=True)
a_name=models.CharField(max_length=255)
class B(models.Model):
a=models.ForeignKey(A)
b_name=models.CharField(max_length=255)
I want to filter B objects which belong to a particular a_id. I can either do this -
B.objects.filter(a=a_id)
or
B.objects.filter(a__a_id=a_id)
Is there any difference between the two, in terms of efficiency, speed or functionality?
B.objects.filter(a=a_id) is much more efficient because it simply filters the values of B.a and avoids joining table A altogether, while B.objects.filter(a__a_id=a_id) requires joining table A by a_id and then filtering a_id with a.

Django ORM: Group By/Min and return full rows

I have a model table like this
Table A
Fields A, B, C, D, E (5 Fields)
I want to group by field B and min by field C so in the end, i need to have a full queryset like
A, B, C, D, E, Min(C)GroupBY(B) (6 Fields).
I know about A.objects.values(B).annotate(min(C)) but it returns only 2 fields and not a full row.
My requirements are to use only pure Django ORM or extra. I can't use raw SQL (limitations for filter, rawqueryset etc) cause i need a queryset to import to Django-Tables2.
Any advice how i can achieve this?

django multiple foreignkeys to the same parent class

I am quite new to Django and I am creating an app which stores unit conversion tables for an application on a mobile device.
Each UnitCategory can have multiple Units, each of which have a multiplication factor to use to convert values between them. The current model could be simplified to this:
class UnitCategory(models.Model):
name=models.CharField(max_length=100)
class Unit(models.Model):
name=models.CharField(max_length=200)
multiplicand=models.FloatField(default=1)
category=models.ForeignKey('UnitCategory',related_name='units_set')
With admin classes:
class UnitCategoryAdmin(admin.ModelAdmin):
model=UnitCategory
inlines=[UnitInline]
class UnitInline(admin.TabularInline):
model=Unit
Now, rather than entering all of the multiplication factors for all potential units, most of the units in many categories can be built as a function of other base categories, e.g a simple case would be: [Speed] = [Distance] x [Time]^-1.
I am trying to add a class to provide another set of inlines to store data for compound conversion. Each inline would have a dropdown list to select a base unit category and an integer field to enter power it is raised to. I know how to create the dropdown list using a ForeignKey, but I am already using one ForeignKey to link the inline model to the UnitCategory, so I end up with two ForeignKeys pointing to the same parent class:
class CompoundConversionCategory(models.Model):
parent=models.ForeignKey('UnitCategory',related_name='compounds_set')
category=models.ForeignKey('UnitCategory',related_name='category_set')
power=models.IntegerField(default=1)
where the admin classes become:
class UnitCategoryAdmin(admin.ModelAdmin):
model=UnitCategory
inlines=[UnitInline,CompoundCategoryInline]
class UnitInline(admin.TabularInline):
model=Unit
class CompoundCategoryInline(admin.TabularInline):
class=CompoundConversionCategory
Not surprisingly, Django doesn't like me using two ForeignKeys to the same parent class. Is there a way to specify that one of them should be linked to a different object than the parent, or some other more appropriate way to to create a dropdown list from the model?
I believe you are looking for admin.InlineModelAdmin.fk_name. (https://docs.djangoproject.com/en/1.7/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin.fk_name)

django one-to-many

Long story short: I have two models, and a database imported from XML. The model layout is as follows:
class A:
ForgeinKey(B)
class B:
list = {A1, A2 ... An}
Is there a replacement for {A1, A2 ... An} that would make B.list return a list of A's.
Edit: The idea is to have a field in B that lists all the A's that are pointing to it. I can't seem to figure out how to call A.objects.* from inside B's definition. I don't even know if that's possible.
Edit2: Solved, thanks everyone for help :)
If I understood correctly, you want B().list to return the result of SELECT * FROM A WHERE B_id = <B.id>?
You have to use related_name, then:
class A(Model):
b = ForeignKey(B, related_name='list')
Or, you can use the default name, "B().A_set"

Filtering inherited objects

I have a base class A . Two derived classes B , C.
Now I have a global class witch contains a many-to-many relation to object A.
Class D:
aObjects : ManyToMany("A")
how could know the real object the filter query return in object D.
I mean : d.objects.get(id=5)
now d has n objects of class A, but they are a mix of A,B or C.
How can get only those of type B in the query.
Thanks in advance.
There's no way to do this automatically. The documentation is quite clear that there's no way to tell from an instance of a base class whether or not it should 'actually' be an instance of a derived class.
The only thing to do is to define a field on the base class that shows what derived type it is, and set this automatically in the the save() method of the various derived classes. Then you can filter on the value of this field.
Will this works for you
filter(lambda x: isinstance(x, B), d.objects.get(id=5))