Domanda

mi piacerebbe utilizzare una vista che ho creato nel mio database come fonte per la mia vista Django.

È possibile, senza utilizzare SQL personalizzato?

******AGGIORNAMENTO 13/02/09************

Come suggeriscono molte risposte, puoi semplicemente creare la tua vista nel database e quindi utilizzarla all'interno dell'API definendola in models.py.

qualche avvertimento però:

  • Manage.py syncdb non funzionerà più
  • la vista ha bisogno della stessa cosa all'inizio del nome di tutti gli altri modelli (tabelle), ad esempio se la tua app si chiama "cosa", la tua vista dovrà essere chiamata cosa_$viewname
È stato utile?

Soluzione

Dal Django 1.1, è possibile utilizzare Options.managed per questo.

Per le versioni precedenti, si può facilmente definire una classe modello per una vista e utilizzarlo come gli altri punti di vista. Ho appena provato utilizzando un'applicazione Sqlite-based e sembra funzionare bene. Basta fare in modo di aggiungere un campo chiave primaria se colonna "chiave primaria" del vostro punto di vista non si chiama 'id' e specificare il nome della vista nelle opzioni Meta se la vista non si chiama 'app_classname'.

L'unico problema è che il comando "syncdb" solleverà un'eccezione poiché Django cercherà di creare la tabella. È possibile evitare che, definendo i 'modelli' vista in un file Python separato, diverso da quello models.py. In questo modo, Django non vederli quando introspezione models.py per determinare i modelli di creare per l'applicazione e per questo non tenterà di creare la tabella.

Altri suggerimenti

Solo un aggiornamento per coloro che si incontrano questa domanda (da Google o qualsiasi altra cosa) ...

Attualmente Django ha una semplice "modo giusto" per definire il modello senza riuscire tabelle del database :

  

Options.managed

     

Il valore predefinito è True, che significa Django creerà le tabelle del database appropriate syncdb e rimuoverli come parte di un comando di gestione reset. Cioè, Django gestisce cicli di vita le tabelle del database.

     

Se False, nessuna creazione tabella di database o operazioni di cancellazione verrà eseguita per questo modello. Questo è utile se il modello rappresenta una tabella esistente o una vista di database che è stato creato con altri mezzi. Questo è il solo differenza quando managed è <=>. Tutti gli altri aspetti della gestione del modello sono esattamente gli stessi come normale.

Ho appena implementato un modello utilizzando una vista con postgres 9.4 e django 1.8.

Ho creato classi di migrazione personalizzate come questa:

# -*- 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)
    ]

Ho scritto il modello come farei normalmente.Funziona per i miei scopi.

Nota- Quando ho eseguito makemigrations è stato creato un nuovo file di migrazione per il modello, che ho eliminato manualmente.

Divulgazione completa: la mia vista è di sola lettura perché sto utilizzando una vista derivata da un tipo di dati jsonb e non ho scritto una regola ON UPDATE INSTEAD.

Abbiamo fatto questo abbastanza ampiamente nelle nostre applicazioni con MySQL per aggirare la limitazione unico database di Django. La nostra applicazione ha un paio di banche dati che vivono in una singola istanza di MySQL. Siamo in grado di realizzare il modello tra database si unisce in questo modo il tempo che abbiamo viste create per ogni tabella nel database "corrente".

Per quanto riguarda inserti / aggiornamenti in vista andare, con i nostri casi d'uso, la vista è fondamentalmente un "select * from [db.table];". In altre parole, non facciamo alcun complesso si unisce o il filtraggio in modo da inserire / aggiornamenti innescano da save () funzionano bene. Se il vostro caso d'uso richiede così complesso si unisce o estesa filtraggio, ho il sospetto che non avrete alcun problema per la sola lettura scenari, ma può incorrere in problemi di inserimento / aggiornamento. Penso che ci sono alcuni vincoli sottostanti in MySQL che impediscono l'aggiornamento in vista che le tabelle attraversano, hanno filtri complessi, ecc

In ogni caso, la vostra situazione potrebbe essere diversa se si utilizza un RDBMS diverso da MySQL, ma Django in realtà non importa se seduto sulla cima di una tabella o vista fisico. Sta andando essere il RDBMS che determina se funziona realmente come ci si aspetta. Come ha osservato un commentatore precedente, probabilmente sarete buttare syncdb fuori dalla finestra, anche se abbiamo lavorato con successo in tutto con un segnale post-syncdb che elimina la tabella fisico creato da Django e gestisce il nostro "... creare view" comando. Tuttavia, il segnale post-syncdb è un po 'esoterica nel modo in cui viene attivato, in modo caveat emptor anche lì.

EDIT: Naturalmente da "segnale post-syncdb" Voglio dire "post-syncdb ascoltatore"

Django Documentazione ufficiale , si potrebbe chiamare la vista in questo modo:

#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()

Speranza che aiuta; -)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top