What is the rationale behind the decision to not support Single Table Inheritance in Django?
Is STI a bad design? Does it result in poor performance? Would it conflict with the Django ORM as it is?
Just wondering because it's been a missing feature for like ten years now and so there must have been a conscious decision made that it would never be supported.
One reason is possibly that Django does not (currently) have the ability to modify database tables after creation.
You can 'kind-of' do STI using proxy models. This will not allow you to have different fields on the different models, but it will allow you to attach different behaviour (via model methods) to different subclasses.
However, if you decide to create a subclass with extra fields, Django will not be able to update the database to reflect that.
Related
This question already has answers here:
django: modifying/extending 3rd party apps
(3 answers)
Closed 3 months ago.
I need to override library model field in Django. This model is integrated in that library and used there. The changes I need is to add a unique constraint to one of the model fields. But this is not the abstract model so I can't inherit this model as I understand.
The question: is there a way to override usual model field in Django without inheritance?
Not that I'm aware of. I'd be looking at modifying (forking) the "library" model, although there might be issues if it's proprietary 3rd party code for which you do not have source.
The usual thing against concrete inheritance is that it causes a new DB table to be created and thereafter, every query involves a join on a OneToOne field between the two tables. However, I'm wondering whether this happens if you merely add a constraint to an existing field. Might be worth investigating in detail.
Likewise, can you inherit merely to subclass the .save() method, and apply the equivalent to a constraint therein? This isn't bullet-proof, because it's enforced only by the saving of Django objects and can be overridden both by django bulk_update and by anybody accessing the DB table without Django. And again, does it end up creating and joining a second DB table even if it contains no fields at all (except a primary key).
Sorry, more questions than a proper answer. Maybe somebody knows these answers?
I've got a situation where I have one base Django model Rolls, mapped to the table rolls. There are multiple types of rolls, controlled by a column called type. In the older codebase I'm writing a v2 for (used to be PHP), I created subclasses for each type, that controlled setting their own type value, and it worked fine. I can't figure out how to set this up in Django.
I'd like them all to use the same table, and each will derive methods from the base model, but have different implementations for many of those methods. I figure I can write a manager to handle getting back the right values, but I can't figure out how to setup the models.
I tried setting a single base model and then derived other models from it, but those created different tables for each of them. Using managed = False seems the wrong way to go, given the subclasses don't represent tables of their own.
You're on the right track, but I believe you want proxy models and not unmanaged ones, e.g. proxy = True:
Sometimes, however, you only want to change the Python behavior of a model – perhaps to change the default manager, or add a new method.
This is what proxy model inheritance is for: creating a proxy for the original model. You can create, delete and update instances of the proxy model and all the data will be saved as if you were using the original (non-proxied) model. The difference is that you can change things like the default model ordering or the default manager in the proxy, without having to alter the original.
Then you could override each subclass' save method to set the correct type, and each subclass' default query manager to filter on that type.
I am building a control panel that will have multiple sub-applications in Django. One of my models is an application, which will have important settings like name, description, install_path and id (so that I can associate specific settings and configuration values to this application.
Right now I'm struggling with trying to figure out how to declare this particular model. Each application will do something completely different than each other application. One might manage specific CMS settings and another may handle password resets for our development environment. The goal is to get the common support items in one place.
The main information for each application will be the same. Each will have a name, description, etc. The difference will be what they do and what settings they use. The settings are in their own model though, with a link back to the application via foreign key.
I'm unsure which model type would be most appropriate for my use case. Both look like they'd be useful, but if that's the case, I'm assuming that I am missing an aspect of one (or both) of them.
My question is, what is the difference between declaring my applications using abstract base class models vs. proxy models?
Nobody's touched this for 8 months. I should know better, but I'm going to take a stab at it.
Your first option, obviously, is to not use base classes at all and duplicate your Fields on each model. I know you didn't ask about this, but for others looking at this post, it is a good way to go for beginners. It's easy, and everything for the model is listed in one place rather than pointing to another model located somewhere else in the code for some of your fields.
Abstract base classes are probably the next easiest and next most commonly used. When you have a lot of duplication of fields across two or more models it is worth considering. Using this method you can eliminate the need to type (or cut and paste) fields over and over across multiple models. When you declare the base class abstract, the table is never actually built in the database. The base class is only used when the child tables are built. This keeps your database simpler and maintains performance because you don't have to build relationships to the base class and use joins to query data. You can also add additional fields (attributes) to the child classes on each of your child models(which proxy models cannot).
Proxy models are somewhat similar in that you have a base or parent class, but there are significant differences from there. You will use proxy models in situations where all of you models have the same fields (attributes), but you might have different "types" of objects. For instance you might have a base class of Cars, and use the manufacturer as your type. Then you may have Ford, Chevy and Honda models that are all proxy models of Cars. They all have the same fields. The manager class chosen for the model is what really makes them different from each other. From a database perspective, really only one table is built... Cars, leading to better performance than building multiple tables, but the drawback is you can't add manufactures-specific fields to the model without adding them to the entire Cars table.
In general I would recommend starting with Abstract Base Classes for models with lots of duplicate fields. Proxy models seem to be a more specific use case, but can be used as well if you have the use case and once you're more well-versed.
I'm not 100% clear on your specific use case based on your description, but hopefully I've given you enough information to decide what's best on your own.
Is it possible to develop an API in Django "TastyPie" in a way which doesn't tie it directly to a "single" Django ORM model? i.e. a call /api/xyz/ would retrieve data from "a", "b" & "c" into a single JSON output. If so, please point me in the right direction.
tastypie is more tightly coupled to the ORM than django-piston, but there are methods that you can define in a tastypie resource to specify how to handle create, read, update, delete: http://readthedocs.org/docs/django-tastypie/en/latest/resources.html?highlight=put_list#obj-get
And you would just not set the queryset meta field.
django-piston on the other hand, has a more direct initial approach to having you define one or more of these methods. The resource can still be bound to a model to give you out of the box REST, but its more up front about showing you the methods to define for custom handling.
tastypie is a bit more robust in its process and features, but it makes this specific feature set a little less apparent.
Tastypie has ModelResource and Resource. The former is tied to a model(which you can override a lot of its methods as jdi suggested) and the latter is what you need I think. Example of Resource here. The example is for a Riak data source, in your case it would be a combination of django models.
I'm using CherryPy, Mako templates, and SQLAlchemy in a web app. I'm coming from a Ruby on Rails background and I'm trying to set up some data validation for my models. I can't figure out the best way to ensure, say, a 'name' field has a value when some other field has a value. I tried using SAValidation but it allowed me to create new rows where a required column was blank, even when I used validates_presence_of on the column. I've been looking at WTForms but that seems to involve a lot of duplicated code--I already have my model class set up with the columns in the table, why do I need to repeat all those columns again just to say "hey this one needs a value"? I'm coming from the "skinny controller, fat model" mindset and have been looking for Rails-like methods in my model like validates_presence_of or validates_length_of. How should I go about validating the data my model receives, and ensuring Session.add/Session.merge fail when the validations fail?
Take a look at the documentation for adding validation methods. You could just add an "update" method that takes the POST dict, makes sure that required keys are present, and uses the decorated validators to set the values (raising an error if anything is awry).
I wrote SAValidation for the specific purpose of avoiding code duplication when it comes to validating model data. It works well for us, at least for our use cases.
In our tests, we have examples of the model's setup and tests to show the validation works.
API Logic Server provides business rules for SQLAlchemy models. This includes not only multi-field, multi-table validations, but multi-table validations. It's open source.
I ended up using WTForms after all.