Initial commit

This commit is contained in:
2024-08-27 20:33:44 +02:00
commit 1f1832267d
14794 changed files with 1599592 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
import itertools
from django.contrib import admin
from treebeard.admin import admin_factory
from treebeard.forms import movenodeform_factory
from treebeard.tests.models import BASE_MODELS, UNICODE_MODELS, DEP_MODELS
def register(admin_site, model):
form_class = movenodeform_factory(model)
admin_class = admin_factory(form_class)
admin_site.register(model, admin_class)
def register_all(admin_site=admin.site):
for model in itertools.chain(BASE_MODELS, UNICODE_MODELS, DEP_MODELS):
register(admin_site, model)

View File

@@ -0,0 +1,15 @@
"""Pytest configuration file
"""
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "treebeard.tests.settings"
import django
def pytest_report_header(config):
return "Django: " + django.get_version()
def pytest_configure(config):
django.setup()

View File

@@ -0,0 +1,10 @@
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "treebeard.tests.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)

View File

@@ -0,0 +1,381 @@
# Generated by Django 3.1.2 on 2021-02-24 20:44
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='AL_TestNode',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sib_order', models.PositiveIntegerField()),
('desc', models.CharField(max_length=255)),
('parent', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children_set', to='tests.al_testnode')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MP_TestNode',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('path', models.CharField(max_length=255, unique=True)),
('depth', models.PositiveIntegerField()),
('numchild', models.PositiveIntegerField(default=0)),
('desc', models.CharField(max_length=255)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MP_TestNodeAlphabet',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('path', models.CharField(max_length=255, unique=True)),
('depth', models.PositiveIntegerField()),
('numchild', models.PositiveIntegerField(default=0)),
('numval', models.IntegerField()),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MP_TestNodeCustomId',
fields=[
('path', models.CharField(max_length=255, unique=True)),
('depth', models.PositiveIntegerField()),
('numchild', models.PositiveIntegerField(default=0)),
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('desc', models.CharField(max_length=255)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MP_TestNodeShortPath',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('path', models.CharField(max_length=4, unique=True)),
('depth', models.PositiveIntegerField()),
('numchild', models.PositiveIntegerField(default=0)),
('desc', models.CharField(max_length=255)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MP_TestNodeSmallStep',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('path', models.CharField(max_length=255, unique=True)),
('depth', models.PositiveIntegerField()),
('numchild', models.PositiveIntegerField(default=0)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MP_TestNodeSorted',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('path', models.CharField(max_length=255, unique=True)),
('depth', models.PositiveIntegerField()),
('numchild', models.PositiveIntegerField(default=0)),
('val1', models.IntegerField()),
('val2', models.IntegerField()),
('desc', models.CharField(max_length=255)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MP_TestNodeSortedAutoNow',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('path', models.CharField(max_length=255, unique=True)),
('depth', models.PositiveIntegerField()),
('numchild', models.PositiveIntegerField(default=0)),
('desc', models.CharField(max_length=255)),
('created', models.DateTimeField(auto_now_add=True)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MP_TestNodeUuid',
fields=[
('path', models.CharField(max_length=255, unique=True)),
('depth', models.PositiveIntegerField()),
('numchild', models.PositiveIntegerField(default=0)),
('custom_id', models.UUIDField(default=uuid.uuid1, editable=False, primary_key=True, serialize=False)),
('desc', models.CharField(max_length=255)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MP_TestSortedNodeShortPath',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('path', models.CharField(max_length=4, unique=True)),
('depth', models.PositiveIntegerField()),
('numchild', models.PositiveIntegerField(default=0)),
('desc', models.CharField(max_length=255)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MP_UnicodeNode',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('path', models.CharField(max_length=255, unique=True)),
('depth', models.PositiveIntegerField()),
('numchild', models.PositiveIntegerField(default=0)),
('desc', models.CharField(max_length=255)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='NS_TestNode',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('lft', models.PositiveIntegerField(db_index=True)),
('rgt', models.PositiveIntegerField(db_index=True)),
('tree_id', models.PositiveIntegerField(db_index=True)),
('depth', models.PositiveIntegerField(db_index=True)),
('desc', models.CharField(max_length=255)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='NS_TestNodeSorted',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('lft', models.PositiveIntegerField(db_index=True)),
('rgt', models.PositiveIntegerField(db_index=True)),
('tree_id', models.PositiveIntegerField(db_index=True)),
('depth', models.PositiveIntegerField(db_index=True)),
('val1', models.IntegerField()),
('val2', models.IntegerField()),
('desc', models.CharField(max_length=255)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='NS_UnicodetNode',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('lft', models.PositiveIntegerField(db_index=True)),
('rgt', models.PositiveIntegerField(db_index=True)),
('tree_id', models.PositiveIntegerField(db_index=True)),
('depth', models.PositiveIntegerField(db_index=True)),
('desc', models.CharField(max_length=255)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='RelatedModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('desc', models.CharField(max_length=255)),
],
),
migrations.CreateModel(
name='AL_TestNodeInherited',
fields=[
('al_testnode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='tests.al_testnode')),
('extra_desc', models.CharField(max_length=255)),
],
options={
'abstract': False,
},
bases=('tests.al_testnode',),
),
migrations.CreateModel(
name='MP_TestNodeInherited',
fields=[
('mp_testnode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='tests.mp_testnode')),
('extra_desc', models.CharField(max_length=255)),
],
options={
'abstract': False,
},
bases=('tests.mp_testnode',),
),
migrations.CreateModel(
name='NS_TestNodeInherited',
fields=[
('ns_testnode_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='tests.ns_testnode')),
('extra_desc', models.CharField(max_length=255)),
],
options={
'abstract': False,
},
bases=('tests.ns_testnode',),
),
migrations.CreateModel(
name='NS_TestNodeSomeDep',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('node', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tests.ns_testnode')),
],
),
migrations.CreateModel(
name='NS_TestNodeRelated',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('lft', models.PositiveIntegerField(db_index=True)),
('rgt', models.PositiveIntegerField(db_index=True)),
('tree_id', models.PositiveIntegerField(db_index=True)),
('depth', models.PositiveIntegerField(db_index=True)),
('desc', models.CharField(max_length=255)),
('related', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tests.relatedmodel')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MP_TestNodeSomeDep',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('node', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tests.mp_testnode')),
],
),
migrations.CreateModel(
name='MP_TestNodeRelated',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('path', models.CharField(max_length=255, unique=True)),
('depth', models.PositiveIntegerField()),
('numchild', models.PositiveIntegerField(default=0)),
('desc', models.CharField(max_length=255)),
('related', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tests.relatedmodel')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MP_TestManyToManyWithUser',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('path', models.CharField(max_length=255, unique=True)),
('depth', models.PositiveIntegerField()),
('numchild', models.PositiveIntegerField(default=0)),
('name', models.CharField(max_length=255)),
('users', models.ManyToManyField(to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='AL_UnicodeNode',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sib_order', models.PositiveIntegerField()),
('desc', models.CharField(max_length=255)),
('parent', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children_set', to='tests.al_unicodenode')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='AL_TestNodeSorted',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('val1', models.IntegerField()),
('val2', models.IntegerField()),
('desc', models.CharField(max_length=255)),
('parent', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children_set', to='tests.al_testnodesorted')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='AL_TestNodeSomeDep',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('node', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tests.al_testnode')),
],
),
migrations.CreateModel(
name='AL_TestNodeRelated',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sib_order', models.PositiveIntegerField()),
('desc', models.CharField(max_length=255)),
('parent', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children_set', to='tests.al_testnoderelated')),
('related', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tests.relatedmodel')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='AL_TestNode_Proxy',
fields=[
],
options={
'proxy': True,
'indexes': [],
'constraints': [],
},
bases=('tests.al_testnode',),
),
migrations.CreateModel(
name='MP_TestNode_Proxy',
fields=[
],
options={
'proxy': True,
'indexes': [],
'constraints': [],
},
bases=('tests.mp_testnode',),
),
migrations.CreateModel(
name='NS_TestNode_Proxy',
fields=[
],
options={
'proxy': True,
'indexes': [],
'constraints': [],
},
bases=('tests.ns_testnode',),
),
]

View File

@@ -0,0 +1,299 @@
import uuid
from django.db import models
from django.contrib.auth.models import User
from treebeard.mp_tree import MP_Node
from treebeard.al_tree import AL_Node
from treebeard.ns_tree import NS_Node
class RelatedModel(models.Model):
desc = models.CharField(max_length=255)
def __str__(self):
return self.desc
class MP_TestNode(MP_Node):
steplen = 3
desc = models.CharField(max_length=255)
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class MP_UnicodeNode(MP_Node):
steplen = 3
desc = models.CharField(max_length=255)
def __str__(self): # pragma: no cover
return self.desc
class MP_TestNodeSomeDep(models.Model):
node = models.ForeignKey(MP_TestNode, on_delete=models.CASCADE)
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class MP_TestNodeRelated(MP_Node):
steplen = 3
desc = models.CharField(max_length=255)
related = models.ForeignKey(RelatedModel, on_delete=models.CASCADE)
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class MP_TestNodeInherited(MP_TestNode):
extra_desc = models.CharField(max_length=255)
class MP_TestNodeCustomId(MP_Node):
steplen = 3
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
desc = models.CharField(max_length=255)
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class NS_TestNode(NS_Node):
desc = models.CharField(max_length=255)
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class NS_UnicodetNode(NS_Node):
desc = models.CharField(max_length=255)
def __str__(self): # pragma: no cover
return self.desc
class NS_TestNodeSomeDep(models.Model):
node = models.ForeignKey(NS_TestNode, on_delete=models.CASCADE)
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class NS_TestNodeRelated(NS_Node):
desc = models.CharField(max_length=255)
related = models.ForeignKey(RelatedModel, on_delete=models.CASCADE)
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class NS_TestNodeInherited(NS_TestNode):
extra_desc = models.CharField(max_length=255)
class AL_TestNode(AL_Node):
parent = models.ForeignKey(
"self",
related_name="children_set",
null=True,
db_index=True,
on_delete=models.CASCADE,
)
sib_order = models.PositiveIntegerField()
desc = models.CharField(max_length=255)
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class AL_UnicodeNode(AL_Node):
parent = models.ForeignKey(
"self",
related_name="children_set",
null=True,
db_index=True,
on_delete=models.CASCADE,
)
sib_order = models.PositiveIntegerField()
desc = models.CharField(max_length=255)
def __str__(self): # pragma: no cover
return self.desc
class AL_TestNodeSomeDep(models.Model):
node = models.ForeignKey(AL_TestNode, on_delete=models.CASCADE)
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class AL_TestNodeRelated(AL_Node):
parent = models.ForeignKey(
"self",
related_name="children_set",
null=True,
db_index=True,
on_delete=models.CASCADE,
)
sib_order = models.PositiveIntegerField()
desc = models.CharField(max_length=255)
related = models.ForeignKey(RelatedModel, on_delete=models.CASCADE)
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class AL_TestNodeInherited(AL_TestNode):
extra_desc = models.CharField(max_length=255)
class MP_TestNodeSorted(MP_Node):
steplen = 1
node_order_by = ["val1", "val2", "desc"]
val1 = models.IntegerField()
val2 = models.IntegerField()
desc = models.CharField(max_length=255)
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class NS_TestNodeSorted(NS_Node):
node_order_by = ["val1", "val2", "desc"]
val1 = models.IntegerField()
val2 = models.IntegerField()
desc = models.CharField(max_length=255)
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class AL_TestNodeSorted(AL_Node):
parent = models.ForeignKey(
"self",
related_name="children_set",
null=True,
db_index=True,
on_delete=models.CASCADE,
)
node_order_by = ["val1", "val2", "desc"]
val1 = models.IntegerField()
val2 = models.IntegerField()
desc = models.CharField(max_length=255)
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class MP_TestNodeAlphabet(MP_Node):
steplen = 2
numval = models.IntegerField()
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class MP_TestNodeSmallStep(MP_Node):
steplen = 1
alphabet = "0123456789"
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class MP_TestNodeSortedAutoNow(MP_Node):
desc = models.CharField(max_length=255)
created = models.DateTimeField(auto_now_add=True)
node_order_by = ["created"]
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class MP_TestNodeShortPath(MP_Node):
steplen = 1
alphabet = "012345678"
desc = models.CharField(max_length=255)
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
class MP_TestNodeUuid(MP_Node):
steplen = 1
custom_id = models.UUIDField(primary_key=True, default=uuid.uuid1, editable=False)
desc = models.CharField(max_length=255)
def __str__(self): # pragma: no cover
return "Node %s" % self.pk
# This is how you change the default fields defined in a Django abstract class
# (in this case, MP_Node), since Django doesn't allow overriding fields, only
# mehods and attributes
MP_TestNodeShortPath._meta.get_field("path").max_length = 4
class MP_TestNode_Proxy(MP_TestNode):
class Meta:
proxy = True
class NS_TestNode_Proxy(NS_TestNode):
class Meta:
proxy = True
class AL_TestNode_Proxy(AL_TestNode):
class Meta:
proxy = True
class MP_TestSortedNodeShortPath(MP_Node):
steplen = 1
alphabet = "012345678"
desc = models.CharField(max_length=255)
node_order_by = ["desc"]
def __str__(self): # pragma: no cover
return "Node %d" % self.pk
MP_TestSortedNodeShortPath._meta.get_field("path").max_length = 4
class MP_TestManyToManyWithUser(MP_Node):
name = models.CharField(max_length=255)
users = models.ManyToManyField(User)
BASE_MODELS = (
AL_TestNode,
MP_TestNode,
NS_TestNode,
MP_TestNodeUuid,
MP_TestNodeCustomId,
)
PROXY_MODELS = AL_TestNode_Proxy, MP_TestNode_Proxy, NS_TestNode_Proxy
SORTED_MODELS = AL_TestNodeSorted, MP_TestNodeSorted, NS_TestNodeSorted
DEP_MODELS = AL_TestNodeSomeDep, MP_TestNodeSomeDep, NS_TestNodeSomeDep
MP_SHORTPATH_MODELS = MP_TestNodeShortPath, MP_TestSortedNodeShortPath
RELATED_MODELS = AL_TestNodeRelated, MP_TestNodeRelated, NS_TestNodeRelated
UNICODE_MODELS = AL_UnicodeNode, MP_UnicodeNode, NS_UnicodetNode
INHERITED_MODELS = (AL_TestNodeInherited, MP_TestNodeInherited, NS_TestNodeInherited)
def empty_models_tables(models):
for model in models:
model.objects.all().delete()

View File

@@ -0,0 +1,92 @@
"""
Django settings for testing treebeard
"""
import os
def get_db_conf():
"""
Configures database according to the DATABASE_ENGINE environment
variable. Defaults to SQlite.
This method is used to run tests against different database backends.
"""
database_engine = os.environ.get('DATABASE_ENGINE', 'sqlite')
if database_engine == 'sqlite':
return {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory:'
}
elif database_engine == 'psql':
return {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'treebeard',
'USER': os.environ.get('DATABASE_USER_POSTGRES', 'treebeard'),
'PASSWORD': os.environ.get('DATABASE_PASSWORD', ''),
'HOST': os.environ.get('DATABASE_HOST', 'localhost'),
'PORT': os.environ.get('DATABASE_PORT_POSTGRES', ''),
}
elif database_engine == "mysql":
return {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'treebeard',
'USER': os.environ.get('DATABASE_USER_MYSQL', 'treebeard'),
'PASSWORD': os.environ.get('DATABASE_PASSWORD', ''),
'HOST': os.environ.get('DATABASE_HOST', 'localhost'),
'PORT': os.environ.get('DATABASE_PORT_MYSQL', ''),
}
elif database_engine == "mssql":
return {
'ENGINE': 'mssql',
'NAME': 'master',
'USER': 'sa',
'PASSWORD': 'Password12!',
'HOST': '(local)\\SQL2019',
'PORT': '',
'OPTIONS': {
'driver': 'SQL Server Native Client 11.0',
},
}
DATABASES = {'default': get_db_conf()}
SECRET_KEY = '7r33b34rd'
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.admin',
'django.contrib.messages',
'treebeard',
'treebeard.tests'
]
MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware'
]
ROOT_URLCONF = 'treebeard.tests.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.template.context_processors.request',
'django.contrib.messages.context_processors.messages',
],
},
},
]

View File

@@ -0,0 +1,54 @@
"""
Check that all changes to Treebeard models have had migrations created in our test app. If there
are outstanding model changes that need migrations, fail the tests.
This module is taken from https://github.com/wagtail/wagtail/blob/master/wagtail/core/tests/test_migrations.py.
"""
from django.apps import apps
from django.db.migrations.autodetector import MigrationAutodetector
from django.db.migrations.loader import MigrationLoader
from django.db.migrations.questioner import MigrationQuestioner
from django.db.migrations.state import ProjectState
from django.test import TestCase
class TestForMigrations(TestCase):
def test__migrations(self):
app_labels = set(app.label for app in apps.get_app_configs() if app.name.startswith('tests.'))
for app_label in app_labels:
apps.get_app_config(app_label.split('.')[-1])
loader = MigrationLoader(None, ignore_no_migrations=True)
conflicts = dict(
(app_label, conflict)
for app_label, conflict in loader.detect_conflicts().items()
if app_label in app_labels
)
if conflicts:
name_str = "; ".join("%s in %s" % (", ".join(names), app) for app, names in conflicts.items())
self.fail("Conflicting migrations detected (%s)." % name_str)
autodetector = MigrationAutodetector(
loader.project_state(),
ProjectState.from_apps(apps),
MigrationQuestioner(specified_apps=app_labels, dry_run=True),
)
changes = autodetector.changes(
graph=loader.graph,
trim_to_apps=app_labels or None,
convert_apps=app_labels or None,
)
if changes:
migrations = '\n'.join((
' {migration}\n{changes}'.format(
migration=migration,
changes='\n'.join(' {0}'.format(operation.describe())
for operation in migration.operations))
for (_, migrations) in changes.items()
for migration in migrations))
self.fail('Model changes with no migrations detected:\n%s' % migrations)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
from django.contrib import admin
from django.urls import path
admin.autodiscover()
urlpatterns = [
path("admin/", admin.site.urls),
]