[Django]-Create database view from django model

24👍

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=[
                # ...
            ],
        ),
    ]

23👍

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.

3👍

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
👤Shohei

Leave a comment