Die ORM-Funktion von Django ist großartig, aber wenn Sie versuchen, ein Modell für eine etwas andere Tabelle zu erstellen, z. B. eine dynamisch erstellte Tabelle oder eine Tabelle in einem bestimmten Postgres-Schema, gibt es nicht viele Informationen.
Wenn Sie versuchen, etwas Kompliziertes zu tun, z. B. die erstellte Tabelle umzuleiten und eine Tabelle mit derselben Definition in einem anderen Schema zu erstellen, dauert die Untersuchung einige Zeit, und der Entwicklungsprozess wird für einige Tage angehalten.
Dieser Artikel ist ein Bericht über die Schwierigkeiten, angesichts dieser Herausforderungen Folgendes zu erreichen.
**
Kurz gesagt, obwohl dies eine etwas komplizierte Anforderung ist, ist die ORM-Funktion unter Verwendung der Modellklasse von Django ausgezeichnet. Daher möchte ich die Vorteile der Tabellenerstellung, Datensatzregistrierung, Suche usw. maximieren.
Die Umgebung ist diesmal wie folgt.
Abschließend war es möglich, die Referenzen anzuwenden. Details werden unten beschrieben.
Für die folgende Erklärung lautet zunächst ein Beispiel für ein Modell, das eine Umleitungsquelle ist, wie folgt.
app/models/model.py
class Compound(models.Model):
name = models.CharField(max_length=1024)
smiles = models.CharField(max_length=4000, null=True)
standard_inchi = models.CharField(max_length=4000, default=None, null=True)
mol = models.TextField(null=True)
image = models.BinaryField(null=True)
Da das Modell der Umleitungsquelle unter der Kontrolle der Migration von Django steht, sollten Sie in der Lage sein, eine Tabelle für das Modell zu erstellen, indem Sie Migration und Migration durchführen. Die Tabelle wird dann im öffentlichen Schema erstellt, sofern Sie keine besonderen Einstellungen vornehmen.
Als nächstes wird die Funktion erklärt, die der Schlüssel zu dieser Zeit ist. Normalerweise ist es in Django erforderlich, im Voraus eine Modellklasse in der Quelle zu erstellen. Diesmal beziehen Sie sich jedoch auf Dynamische Modelle und erstellen das gewünschte Modell. Ich habe eine Funktion vorbereitet, um dynamisch eine Klasse zu erstellen. Insbesondere kann ein neues Modell erstellt werden, indem das Schema, der Tabellenname und die Modellklasse der Umleitungsquelle angegeben werden. Die Quelle ist wie folgt. Es ist zu beachten, dass wo für die Funktion erstellt werden kann, diese aber im selben Modul und in der aktuellen Umleitungsquelle definiert sind.
app/models/model.py
def create_model_by_prototype(model_name, schema_name, table_name, prototype):
import copy
class Meta:
pass
setattr(Meta, "db_table", schema_name + "\".\"" + table_name)
fields = {}
for field in prototype._meta.fields:
fields[field.name] = copy.deepcopy(field)
attrs = {'__module__': "app.models.models", 'Meta': Meta}
attrs.update(fields)
model = type(model_name, (models.Model,), attrs)
return model
Wir werden uns später spezifische Verwendungsbeispiele ansehen und die Quelle kurz erläutern.
`für Feld in prototype._meta.fields:`
bereiten wir vor, das Feld des zu umzuleitenden Modells auf das Feld des diesmal zu erstellenden Modells festzulegen.`type (model_name, (models.Model,), attrs)`
eine neue Model-Klasse generiert und basierend auf den vorbereiteten Attributinformationen zurückgegeben.Lassen Sie uns nun das Verwendungsbild der Funktion sehen, die die erstellte Funktion von Hand mit der Django-Shell verwendet.
Dies wird weggelassen, da nur Djangos Makemigrationen ausgeführt und migriert werden.
Das Schema zum Speichern der neuen Tabelle war diesmal problematisch, daher habe ich es erstellt, indem ich eine direkte Verbindung zu Postgres hergestellt habe. Der Schemaname lautet user01.
create schema user01;
$ python manage.py shell
Python 3.7.6 | packaged by conda-forge | (default, Jun 1 2020, 18:11:50) [MSC v.1916 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.16.1 -- An enhanced Interactive Python. Type '?' for help.
Importieren Sie anschließend die zur Verwendung der Funktion erforderlichen Module.
from chempre.models.models import Compound
from chempre.models import models
Jetzt erstellen wir ein Modell dynamisch mit der erstellten Funktion. Hier wird ein Modell namens Compound verwendet, und eine Tabelle mit dem Namen my_compound mit derselben Definition wird in dem zuvor erstellten user01-Schema erstellt.
model= models.create_model_by_prototype("MyCompound", "user01", "my_compound", Compound)
Erstellen Sie als Nächstes eine Tabelle, die dem Modell entspricht. Da dieses Modell nicht durch Migration verwaltet wird, wird es anders als gewöhnlich erstellt. Das Verfahren ist wie folgt.
from django.db import connection
with connection.schema_editor() as schema_editor:
schema_editor.create_model(model)
Dadurch wird eine Tabelle im Schema user01 erstellt. Wenn ich mich tatsächlich mit psql mit Postgres verbinde, wird es mit Sicherheit erstellt.
Als nächstes registrieren wir die Daten. Da es schwierig war, das Feld anzugeben, erstelle ich hier einen Datensatz, bei dem nur das Namensfeld festgelegt ist.
model.objects.create(name='compound name')
Lassen Sie uns suchen und prüfen, ob die Tabelle erstellt wurde.
compound=model.objects.get(id=1)[
print(compound.name)
Wenn registriert, sollte der Wert 'Compund Name' angezeigt werden. Wenn ich tatsächlich mit psql eine Verbindung zu Postgres herstelle, wird mit Sicherheit ein Datensatz erstellt.
Ich konnte sicher alles erreichen, was ich ursprünglich erreichen wollte. Ich möchte das Gangan-Modell auf diese Weise in Serie produzieren und das Django-Leben genießen. Django hat eine Menge Taktiken und eine Menge zu merken, aber es hat nicht die Robustheit und Inflexibilität, die für diese Art von Framework typisch ist, und es scheint, dass es flexibel angepasst werden kann.
Recommended Posts