I learned sql \"view\" as a virtual table to facilitate the SQL operations, like
MySQL [distributor]> CREATE VIEW CustomerEMailList AS
-> SELECT cust_
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 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=[
# ...
],
),
]
According to the Django ORM Cookbook by Agiliq, you can do it like the following.
Create view:
create view temp_user as
select id, first_name from auth_user;
Create a model which is not managed and naming a db_table explicitly:
class TempUser(models.Model):
first_name = models.CharField(max_length=100)
class Meta:
managed = False
db_table = "temp_user"
You'll be able to query then, but you'll receive an error once you try to update.
Query like always:
TempUser.objects.all().values()
I haven't tried this yet, but I certainly will.
I created a Django plugin which you can create a view table. You can check it here, on pypi.org
Install with pip install django-view-table
and set INSTALLED_APPS
like this:
INSTALLED_APPS = [
'viewtable',
]
And so, a view table model can be written as follows:
from django.db import models
from view_table.models import ViewTable
# Base table
class Book(models.Model):
name = models.CharField(max_length=100)
category = models.CharField(max_length=100)
# View table
class Books(ViewTable):
category = models.CharField(max_length=100)
count = models.IntegerField()
@classmethod
def get_query(self):
# Select sql statement
return Book.objects.values('category').annotate(count=models.Count('category')).query
Finally, create the table:
python manage.py createviewtable