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).
Related
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.
I recently had a django question - and one of the answers left me stumped:
https://stackoverflow.com/a/10608687/1061426
I've read the django doco, but cannot quite work out how mixins are relevant to what was asked, or what the answer is referring to.
So, I searched for "django mixin tutorial" and stumbled across something called dajax and dajaxice. Ok, i am lying, i came across this blog:
http://www.pythondiary.com/blog/Apr.15,2012/stay-tuned-django-ajax-tutorial.html
My question is:
What are mixins? How do they relate to ajax calls? Are they used for things other than ajax? Why would i want to use dajax or dajaxice or some other django addin framework, rather than just plain django to work with ajax?
Also, there isn't a dajax tag, but there is a dajaxice tag for stackoverflow... does that mean that dajaxice is The Way To Go?
Cheers,
Mixins are a general Object Oriented Programming concept. They don't specifically have anything to do with Django or Dajax, etc. However, Django does, and Dajax probably as well, use mixins.
In general, a "mixin" is simply a class that is meant to literally be mixed in with another class. It typically doesn't do anything on its own, but rather, merely adds functionality to another class. Django's concept of "abstract" models are an example of a mixin. You never instantiate an abstract model. Instead, other models inherit from the abstract model, gaining all of its functionality, and it's those subclasses that actually are instantiated.
Django's class-based views (which is what the answer that brought you here is talking about) also use mixins. For example, most of the class-based views inherit from TemplateResponseMixin. This class is not a view itself, and you would never use it for anything but for a class-based view to inherit from. It's merely an encapsulation of all the functionality that renders a template into a response, so this functionally can be "mixed in" to all the various views without violating DRY (Don't Repeat Yourself).
No, mixins don't have anything in particular to do with Ajax.
A mixin is just a class that can be used as part of the multiple inheritance for another class. Django uses these extensively in its class-based views - some classes provide (for example) the basic functionality for displaying forms, or lists of models, and you are meant to mix those in with your own classes: create your own code that implements your own extensions to that functionality, while inheriting from one or more mixins.
I've never used Dajax, but I suppose it also uses mixins to provide the basic implementation of the Ajax handling within your views.
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.
how do you use MV in Qt? I've tried these two approaches:
If there is an existing/legacy
code "data"-classes, I use model
as a facade. The
Model-implementation class gets a
reference to data, and calls its
functions on model-item access
calls.
For new implementations I derive
the data class from QAbstractModel.
Is there any other way you do it?
The approach I ended up taking is similar to the one you suggest. I am currently using a facade to map between my legacy data model into the QAbstractModel.
At first the facade was a bit too complicated, but slowly I am pulling functionality out of the facade model and pushing it into my data model. And then one day I will remove the facade completely so that my model is THE model.
Having a single model will make my head hurt less.
The MV-code in Qt is a bit messy and feels arkward to implement. Especially if you have to implement hierarchical lists (tree views).
Depending on your need I found that using the QListWidget, QTableWidget and QTreeWidget convenience classes can be much less painful in some cases.
'm developing a 2D game and I want separate the game engine from the graphics.
I decided to use the model-view pattern in the following way: the game engine owns game's entities (EnemyModel, BulletModel, ExplosionModel) which implement interfaces (Enemy, Bullet, Explosion).
The View receives events when entities are created, getting the pointer to the interface: in this way the View can only use the interface methods (i.e. ask for informations to perform the drawing) and cannot change the object state. The View has its onw classes (EnemyView, BulletView, ExplosionView) which own pointers to the interfaces.
(There is also an event-base pattern involved so that the Model can notify the View about entity changes, since a pure query approach is impraticable but I wont' discuss it here).
*Model classes use a compile-time component approach: they use the boost::fusion library to store different state componets, like PositionComponent, HealthComponent and so on.
At present moment the View isn't aware of the component based design but only of the model-view part: to get the position of an enemy it calls the Enemy::get_xy() method. The EnemyModel, which implements the interface, forwards this call to the PositionComponent and returns the result.
Since the bullet has position too, I have to add the get_xy method to Bullet too. BulletModel uses then the same implementation as the EnemyModel class (i.e. it forwards the call).
This approch then leads to have a lot of duplicate code: interfaces have a lot of similar methods and *Model classes are full of forward-methods.
So I have basically two options:
1) Expose the compoment based design so that each component has an interface as well: the View can use this interface to directly query the component. It keeps the View and the Model separated, only at a component level instead of a entity level.
2) Abandon the model-view part and go for pure component based design: the View is just a component (the RenderableComponent part) which has basically full access to the game engine.
Based on your experience which approach would be best?
I'll give my two cents worth. From the problem you're describing, it seems to me that you need an abstract class that will do the operations that are common amongst all of your classes (like the get_xy, which should apply to bullet, enemy, explosion, etc.). This class is a game entity that does the basic grunt work. Inheriting classes can override it if they want.
This abstract class should be the core of all your interfaces (luckily you're in C++ where there is no physical difference between a class, and abstract class and an interface). Thus the Views will know about the specific interfaces, and still have the generic entity methods.
A rule of thumb I have for design - if more than one class has the same data members or methods, it should probably be a single class from which they inherit.
Anyway, exposing the internal structure of your Model classes is not a good idea. Say you'll want to replace boost with something else? You'd have to re-write the entire program, not just the relevant parts.
MVC isn't easy for games as when the game becomes larger (including menu, enemies, levels, GUI...) and transitions, it'll break.
Component or entity-system are pretty good for games.
As a simpler case for you, you may consider using a HMVC. You'll still have issues with transitions, but at least your code will be grouped together in a more clean manner. You probably want your tank's code (rendering and logic) to get close together.
There have been presentation architectures designed especially for agent-based systems, such as Presentation-Abstraction-Control. The hard part in designing such a system is that you ultimately end up hardwiring sequences of collaborations between the agents.
You can do this, but don't use OO inheritance to model the message passing hierarchy. You will regret it. If you think about it, you are really not interested in using the OO inheritance relationship, since the interfaces defined are really just a "Record of functions" that the object can respond to. In that case, you are better off formally modeling your communication protocol.
If you have questions, please ask -- this is not an obvious solution and easy to get wrong.