I learned sql "view" as a virtual table to facilitate the SQL operations, like
MySQL [distributor]> CREATE VIEW CustomerEMailList AS
-> SELECT cust_id, cust_name, cust_email
-> FROM Customers
-> WHERE cust_email IS NOT NULL;
Query OK, 0 rows affected (0.026 sec)
MySQL [distributor]> select * from customeremaillist;
+------------+---------------+-----------------------+
| cust_id | cust_name | cust_email |
+------------+---------------+-----------------------+
| 1000000001 | Village Toys | sales@villagetoys.com |
| 1000000003 | Fun4All | jjones@fun4all.com |
| 1000000004 | Fun4All | dstephens@fun4all.com |
| 1000000005 | The Toy Store | kim@thetoystore.com |
| 1000000006 | toy land | sam@toyland.com |
+------------+---------------+-----------------------+
5 rows in set (0.014 sec)
When I checked the Django documentation subsequently, there are no such functionality to create a virtual "model table" which could simplify the data manipulation.
Should I forget the virtual table "view" when using Django ORM?
Django has - as far as I know at the moment - no builtin support for views.
But you can construct such views, by using the django-database-view
package.
After installing the package (for example with pip):
pip install django-database-view
Furthermore the dbview
app has to be registered in the settings.py
file:
# settings.py
INSTALLED_APPS = (
# ...
'dbview',
# ...
)
Now you can construct a view, this looks a bit similar to the construction of a model, except that you need to implement a view(..)
function that specifies the query behind the view. Something similar to:
from django.db import models
from dbview.models import DbView
class CustomerEMailList(DbView):
cust = models.OneToOneField(Customer, primary_key=True)
cust_name = models.CharField()
cust_email = models.CharField()
@classmethod
def view(klass):
qs = (Customers.objects.filter(cust_email__isnull=False)
.values('cust_id', 'cust_name', 'cust_email'))
return str(qs.query)
Now we can make a migrations:
./manage.py makemigrations
Now in the migration, we need to make a change: the calls to migrations.CreateModel
that are related to the constructed view(s), should be changed to the CreateView
of the dbview
module. Something that looks like:
from django.db import migrations
from dbview import CreateView
class Migration(migrations.Migration):
dependencies = []
operations = [
CreateView(
name='CustomerEMailList',
fields=[
# ...
],
),
]