Pergunta

Eu gostaria de usar uma exibição que eu criei em meu banco de dados como fonte para o meu django-view.

Isso é possível, sem usar sql personalizado?

****** 13/02/09 ATUALIZAÇÃO ***********

Como muitas das respostas sugerem, você pode simplesmente fazer a sua própria visão no banco de dados e, em seguida, usá-lo dentro da API, definindo-o em models.py.

algum aviso:

  • syncdb manage.py não vai mais funcionar
  • a visão precisa a mesma coisa no início de seu nome como todos os outros modelos (tabelas) por exemplo, se seu aplicativo é chamado de "coisa" então sua visão terá de ser chamado thing_ $ viewname
Foi útil?

Solução

Desde Django 1.1, você pode usar Options.managed para isso.

Para versões mais antigas, você pode facilmente definir uma classe modelo para uma visão e usá-lo como seus outros pontos de vista. Eu só testei usando um aplicativo baseado em SQLite e parece funcionar bem. Apenas certifique-se de adicionar um campo de chave primária se coluna "chave primária" do seu ponto de vista não é chamado 'id' e especifique o nome da vista nas opções Meta se o seu ponto de vista não é chamado de 'app_classname'.

O único problema é que o comando "syncdb" irá gerar uma exceção desde Django irá tentar criar a tabela. Você pode evitar que, ao definir os 'modelos de exibição' em um arquivo Python separados, diferentes do que models.py. Desta forma, o Django não vai vê-los quando introspecção models.py para determinar os modelos para criar para o aplicativo e portanto não tentará criar a tabela.

Outras dicas

Apenas uma atualização para aqueles que vai encontrar esta questão (do Google ou qualquer outra coisa) ...

Atualmente Django tem um simples "bom caminho" para definir modelo sem gerenciamento de banco de dados tabelas :

Options.managed

O padrão é True, ou seja, o Django irá criar as tabelas de banco de dados adequadas syncdb e removê-los como parte de um comando de gerenciamento reset. Ou seja, Django administra lifecycles as tabelas de banco de dados.

Se as operações False, nenhuma criação de tabelas de banco de dados ou eliminação será executada para este modelo. Isso é útil se o modelo representa uma tabela existente ou uma exibição de banco de dados que foi criado por outros meios. Esta é a diferença única quando managed é False. Todos os outros aspectos do manejo modelo são exatamente o mesmo que normal.

Eu só implementou um modelo usando uma exibição com Postgres 9.4 e Django 1.8.

Eu criei aulas de migração personalizado como este:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0002_previousdependency'),
    ]

    sql = """
    create VIEW myapp_myview as
     select your view here
    """

    operations = [
        migrations.RunSQL("drop view if exists myapp_myview;"),
        migrations.RunSQL(sql)
    ]

Eu escrevi o modelo como eu normalmente faria. Ele funciona para os meus propósitos.

Nota -. Quando eu corri makemigrations um novo arquivo de migração foi criado para o modelo, que eu deletei manualmente

completa disclosure- meu ponto de vista é somente leitura porque eu estou usando uma visão derivada de um tipo de dados jsonb e não ter escrito um ON Update em vez governar.

Nós fizemos isso muito amplamente em nossas aplicações com MySQL para contornar a limitação de banco de dados único de Django. Nosso aplicativo tem um par de bancos de dados que vivem em uma única instância MySQL. Podemos alcançar modelo cross-database junta-se desta forma o tempo que temos vistas criadas para cada tabela no banco de dados "atual".

Quanto inserções / atualizações em vista ir, com os nossos casos de uso, a vista é basicamente um "SELECT * FROM [db.table];". Em outras palavras, nós não fazemos qualquer complexo junta ou filtrando assim insert / atualizações gatilho de save () funcionam muito bem. Se o seu caso de uso requer tão complexo junta ou filtragem extensa, eu suspeito que você não terá nenhum problema para cenários somente leitura, mas pode executar em problemas insert / update. Eu acho que existem alguns constrangimentos subjacentes no MySQL que o impedem de atualização em vista que as tabelas cruzadas, têm filtros complexos, etc.

De qualquer forma, sua milhagem pode variar se você estiver usando um RDBMS diferente do MySQL, mas Django não se importa se o seu sentado em cima de uma mesa física ou vista. Vai ser o RDBMS que determina se ele realmente funciona como você espera. Como um comentarista anterior conhecida, é provável que você estar jogando syncdb para fora da janela, embora trabalhado com sucesso em torno dele com um sinal de pós-syncdb que cai da mesa física criado por Django e corre o nosso comando "create view ...". No entanto, o sinal pós-syncdb é um esotérico pouco na forma como ele é acionado, então caveat.emptor lá também.

EDIT: Claro por "sinal de pós-syncdb" Quero dizer "pós-syncdb ouvinte"

A partir Django Oficial , você poderia chamar o ponto de vista como este:

#import library
from django.db import connection

#Create the cursor
cursor = connection.cursor()

#Write the SQL code
sql_string = 'SELECT * FROM myview'

#Execute the SQL
cursor.execute(sql_string)
result = cursor.fetchall()

Hope isso ajuda; -)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top