This question is fundamentally similar to these previous questions:
Django access to subclasses items from abstract class
How to query abstract-class-based objects in Django?
I am posting this as a new, separate question because:
I have minor additional considerations that aren't addressed in the previous questions
The previous questions are relatively old, and if it's the case that the correct answer has changed in recent times, I wonder if maybe those questions haven't been visible enough (given that they have accepted answers) to get the attention of those who might know about such potential changes.
With that in mind, I'll take the question from the top and define it fully and concretely - and I leave it to the hive to determine if a close-duplicate is in order.
Background
Say I am constructing models to represent parts of a building. I split the building into logical classes:
Floor
BuildingSpace(ABC)
Office(BuildingSpace)
CommonArea(BuildingSpace)
Goal
Under Floor, I want methods that can retrieve all buildingspaces - or, either of its two subclasses separately:
from typing import Type
class Floor(models.Model):
def getAllSpaces():
# return all objects that satisfy Type[BuildingSpace]
def getAllOffices():
# return all objects that satisfy strictly and only Type[Office]
def getAllCommonAreas():
# return all objects that satisfy strictly and only Type[CommonArea]
Possible solutions
django-model-utils looks like it can support this kind of a query out-of-the-box with its InheritanceManager and the .select_subclass() method -- but, crucially, requires BuildingSpace to be concrete, so that leaves this solution with having to go with multi-table inheritance. Which I understand amplifies database load for each query, so I looked into making the subclasses proxies in order to mitigate that, but InheritanceManager doesn't support proxies. When all is said and done, django-model-utils look to me like it unavoidably opens me to multi-table inheritance penalties at query time.
django-polymorphic also supports this out-of-the-box as far as I have been able to glean, using .instance_of(subclass). Purely from a coding point-of-view, this approach looks very clean and easy to use. But it also looks to come with database performance considerations, and making it admin-panel compliant looks non-trivial at a first, superficial glance.
Natively, it looks django can do this in some roundabout way, but I've seen claims that achieving the same functionality as described above with a native QuerySet.filter() approach is worse performance-wise than both of the above extensions.
A final alternative solution I've briefly considered, that I assume will work natively without creating database considerations (but does require a slight redesign) - is to access the subclass managers directly, and then have the desired outcome of getAllSpaces() implemented via a QuerySet.Union-type of approach.
Almost-MRE
Naïve setup of how I had imagined to be able to use the code:
class BuildingSpace(models.Model):
floor = models.ForeignKey('Floor',
on_delete=models.CASCADE,
related_name="interiors")
class Meta:
abstract = True
class Floor(models.Model):
def _InteriorManager(self): # get the default manager of BuildingSpace
return self.interiors
def GetAllInteriors(self):
return self._InteriorManager().all() # get the full Type[BuildingSpace] queryset, but this isn't supported in native django
def GetOffices(self):
return self._InteriorManager().instance_of(Office) # django-polymorphic
def GetCommonAreas(self):
return self._InteriorManager().select_subclasses(CommonAreas).all() # django-model-utils
Question
I'm hoping to get answers that can weigh in on the following factors:
is there any significant difference in performance between django-model-utils, django-polymorphic and some other best-case QuerySet.filter()-based approach for the cases described here (and potentially, the linked questions at the top)
does either extension implicate any other consideration that is worth noting (ease of use, extensibility, how additional filtering is done, etc)
would my "final alternative solution" in the end maybe work better on all accounts (performance, ease of use, extensibility) if it is the case that the use-cases I need solved are never more complex than the concrete code examples I've provided
I have no insights as to the database performance topic as of yet, but I will say this:
django-polymorphic is really smooth to use. Minimal code adaptation required, and the syntax is both short and intuitive. The perceived difficulty of making it compliant with the admin-panel was a smokescreen, at least as long as you do basic, straightforward subclassing.
For anyone coming this way with similar troubles, don't hesitate to try it. You can't use it on abstract classes, as mentioned, but unless you have really particular needs it does look like having a concrete superclass and just using this library is a whole lot easier than jerry-rigging a manual solution similar to the one I described in the question.
Related
I'm working on a small Django project and I noticed there are different ways to write a view.
What's the difference between a view created with a class and a view created with a function?
When should I use which one?
Thanks!
It has all the same differences that are between Procedural Programming and Object Oriented Programming. It makes sense to write functions for extremely simple views, but not beyond that. There is nothing worse than stuffing 400 lines of code into one big function called view, which becomes a nightmare to read, refactor or test.
In addition to that, Django generic views exploit Template Method design pattern and provide a lot of already written common code for generic use cases, which can often be easily extended to one's needs.
The most important advantage of using a class based views is inheritance.
When working on a big projects, its highly possible to come across multiple views which have similar use, hence you can inherit a class based view to write a new more specific view which is custom to the required method, or you could just reuse the already defined view as is if it serves the purpose.
Generally the function based views are used when the class based views become too complex to implement.
If you are working on a small project you could just use function based views as it will appear to you that the class based views are little more painful to write (At least i felt like it).
I have an app with my own - user defined class and I also use Qt framework libraries to initiate objects of other classes that are built-in. So in my class let's call it 'myclass' I create instances of Qt built-in classes and work on them. THIS IS DONE ... Now, I need to create class diagram for that. I was wondering to which out of Association, Aggregation, Composition or Generalization this could this be classified as ?
Thanks
It is not generalization as you are not inheriting in here, so it cannot qualify as an "is-a" relationship.
As for association, composition or aggregation... here you can find a pretty good explanation which is which. It is not possible to tell the right one for you without knowing your use case better. However, reading the other link will help you to understand the differences and judge based on your scenario.
Difference between association, aggregation and composition
Hope that helps.
The important thing to keep in mind about UML is that there's often no actual right or wrong answer when deciding on what to use, but some tools are better than others. UML is simply a tool for communication and as long as the tool is used in a way that everyone understands what is being communicated, then it serves its purpose.
For a class diagram, at its most basic level, you could actually model everything with just Association and Generalisation, but then this would lack detail that others may want to see.
Generalisation has a one to one relationship with inheritance, so it's clear when to use that.
Association describes any class with a relationship or dependancy with another class; quite a generalisation there(!) which is why it could be used in replacement of Aggregation and Composition.
Aggregation is used when an object (B) makes up another object (A) and B can be shared amongst other objects. For example, a library consists of books, so a book could be modelled as an aggregate of the library because other classes, could also aggregate a book, such as the person borrowing it.
Use composition when an object (B) is used directly to make up an object (A). In this case, if you were modelling the human body and had classes of organs, you would model a heart class as a composition object of a body class.
The fact that you're using the Qt framework is irrelevant to what you use to model your classes and a diagram doesn't need to model everything, just what is necessary to communicate concepts to others.
If, for example you're using container classes such as QList and QMap, you probably don't even want those in the diagram, but if you were to use QTcpSocket and inherit from it, then it may be better to show that.
Just remember, it's all about what you're trying to communicate.
I'm writing an app in Django where I'd like to make use of implicit inheritence when using ForeignKeys. As far as I'm concerned the only way to handle this nicely is to use django_polymorphic library (no single table inheritence in Django, WHY OH WHY??).
I'd like to know about the performance implications of this solution. What kind of joins are performed when doing polymorphic queries? Does it have to hit the database multiple times as compared to regular queries (the infamous N+1 queries problem)? The docs warn that "the type of queries that are performed aren't handled efficiently by the modern RDBMs"? However it doesn't really tell what those queries are. Any statistics, experiences would be really helpful.
EDIT:
Is there any way of retrieving a list of objects, each being an instance of its actual class with a constant number of queries ?? I thought this is what the aforementioned library does, however now I got confused and I'm not that certain anymore.
Django-Typed-Models is an alternative to Django-Polymorphic which takes a simple & clean approach to solving the single table inheritance issue. It works off a 'type' attribute which is added to your model. When you save it, the class is persisted into the 'type' attribute. At query time, the attribute is used to set the class of the resulting object.
It does what you expect query-wise (every object returned from a queryset is the downcasted class) without needing special syntax or the scary volume of code associated with Django-Polymorphic. And no extra database queries.
In Django inherited models are internally represented through an OneToOneField. If you are using select_related() in a query Django will follow a one to one relation forwards and backwards to include the referenced table with a join; so you wouldn't need to hit the database twice if you are using select_related.
Ok, I've digged a little bit further and found this nice passage:
https://github.com/bconstantin/django_polymorphic/blob/master/DOCS.rst#performance-considerations
So happily this library does something reasonably sane. That's good to know.
I just starting on WPF with MVVM, so forgive any misconceptions. I have a model (not a view model but the actual model) that has many List inside classes that are in other List making trees of data.
Important, the data should be XML Serializabled, currently there is no problem doing that with regular properties and List.
The View Model of this class is taking a lot more work than I expected and I'm thinking on converting some or maybe all of the List to ObservableCollections, what are the pros and cons of that?
Also, what would be best in a "bindable model", NotifyPropertyChange or DependencyProperties? I think there would be some memory gains with DependencyProperty since many objects will use default values on most of the properties, what about performance in general, and has it any problems with serialization?
Regards,
The View Model of this class is taking a lot more work than I expected and I'm thinking on converting some or maybe all of the List to ObservableCollections, what are the pros and cons of that?
There is a bit more overhead in ObservableCollection<T> when compared to List<T>, but it does make it easier as data binding directly to your model collections will work.
Also, what would be best in a "bindable model", NotifyPropertyChange or DependencyProperties?
I would not use DependencyProperties within your model. This is taking a dependency on the WPF libraries, and very platform specific. If you want to be able to data bind directly to your model, implementing INotifyPropertyChanged is a reasonable approach.
However, you really should stop and take a minute before making any of these changes. If you're changing your model classes primarily to use them in your View, you're violating the basic principles of MVVM (and most other architectural patterns). One of the main goals here is that your Model is unaware of the presentation layer being used - this makes it more flexible in the future, as you can change presentation layers without changing your model at all.
Our application exposes queries by way of web services, and what we've found is that our clients often want custom queries, either by way of further limiting the results returned by specifying additional criteria, or by asking for things that we don't already expose.
Now, we can take the approach of creating new methods for each of these new methods, but that's somewhat inconvenient; deployment of our application at a client site usually requires weeks of staged integration testing. We've proposed a named query mechanism, where the application administrator would define queries by name that are parameterized, and a corresponding web service that simply invokes these parameters. However, I can't help but think that someone has solved this problem before, so I'd like some input from the SO community on possible designs.
Thanks!
Updates
The specification pattern is a good one, but our application deals with enough data that we want to push as much of the querying work down into an RDBMS, which can do a better job of optimizing the query plan than we would ever want to. Moreover, we support three RDBMS backends, so we're stuck using a greatest-common-denominator approach: we use as much capability as the least functional database can provide.
I would also recommend to consider the "Specification Pattern" in this type of applications as a design decision for your backend. Check the following posts about "Specification Pattern":
http://www.mattberther.com/2005/03/25/the-specification-pattern-a-primer/
http://devlicio.us/blogs/jeff_perrin/archive/2006/12/13/the-specification-pattern.aspx
Take a look at Hibernates Criteria API and use it or build some similar
functionality for Your users.
If it's worth the effort, provide a tree-like interface for grouping criterias. ("all criteria of a group must match" / "one criteria must match" / "negate")
Advantages:
Easy to build.
User parameters are possible.
Powerful queries are possible.
You can apply restrictions like SELECT ... FROM table WHERE someRestriction AND (user-provided criteria)
Since we really don't know which how your users use your interface it seems a little premature to give a technical advice on something that feels a lot closer to "Inmates are running the Asylum" problem.
There are some very good advice and common ways to solve this i technical aspects but do they work for your users? Maybe the really don't give a crap about your problem but rather have a fine working one button solution? (Or more like google?)