I wrote How to make hello world with one file before. The thing you want to try most with django may be the ORM part. How to try the ORM part with only one file.
It takes a bit of work to try it out in one file, but with django these days it's fairly easy to do.
Specifically, the following work is required.
--Set settings from python side --Register model in django's Application Registry --Generate a table for each model
If there is no settings, the following exception will occur.
django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
As per the error message, either register DJANGO_SETTINGS_MODULE
as an environment variable or callsettings.configure ()
.
The minimum required settings are as follows.
from django.conf import settings
settings.configure(
DEBUG=True,
DATABASES={"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": ":memory:"
}},
INSTALLED_APPS=[__name__]
)
DEBUG = True
is necessary when outputting the query result of sql, so it is better to add it. In addition, DB settings are required. Here, the on-memory DB of sqlite is specified. For ʻINSTALLED_APPS, if you forget to specify it when registering the model described later, the relationship of
ManyToMany` will not work properly.
Call django.setup ()
. This will call populate ()
in django.apps.registry.Apps
. In this, the model will be registered in the registry of django. If this is not done, the following error will occur at the timing when Model.save ()
is called.
django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.
Also, as a caveat, set ʻapp_label` to the model to be defined. Without this, the model class cannot be generated. I get the following error.
IndexError: list index out of range
When defining it, do as follows.
class X(models.Model):
name = models.CharField(max_length=255, default="foo", blank=True)
class Meta:
app_label = __name__
Normally, you will generate a DB table with python manage.py migrate
etc. There is no procedure for one file. You need to think about other ways.
For example, let's create a function that creates a table.
from django.db import connections
from django.core.management.color import no_style
def create_table(model):
connection = connections['default']
cursor = connection.cursor()
sql, references = connection.creation.sql_create_model(model, no_style())
for statement in sql:
cursor.execute(statement)
for f in model._meta.many_to_many:
create_table(f.rel.through)
#It is necessary to generate one by one
create_table(X)
The above can be summarized as follows. With this, you can easily check the behavior of the model.
# -*- coding:utf-8 -*-
import django
from django.db import models
from django.conf import settings
from django.db import connections
from django.core.management.color import no_style
settings.configure(
DEBUG=True,
DATABASES={"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": ":memory:"
}},
INSTALLED_APPS=[__name__]
)
def create_table(model):
connection = connections['default']
cursor = connection.cursor()
sql, references = connection.creation.sql_create_model(model, no_style())
for statement in sql:
cursor.execute(statement)
for f in model._meta.many_to_many:
create_table(f.rel.through)
class X(models.Model):
name = models.CharField(max_length=255, default="foo", blank=True)
class Meta:
app_label = __name__
if __name__ == "__main__":
import logging
logging.basicConfig(level=logging.DEBUG)
django.setup()
create_table(X)
xs = X.objects.bulk_create([X(id=1), X(id=2), X(id=3)])
print(X.objects.count())
Recommended Posts