Let's say i have 10 tables in 1 Db and the table names differ and data is different, but the structure of the tables are the same. And then i have 1 more table that collects all the table names and the creation date of that table.
Example:
PrimaryTable
table_name_1
table_name_2
....
table_name_10
and the structure of all tables example:
class PrimaryTable(models.Model):
name = models.CharField(db_column='Name', unique=True, max_length=100)
date = models.CharField(db_column='Date', max_length=100)
class Meta:
managed = True
db_table = 'Primary Table'
def __str__(self):
return self.name
class table_name_1(models.Model):
title = models.TextField(db_column='Title', blank=True, null=True)
url = models.CharField(db_column='Url', unique=True, max_length=250, blank=True,
null=True)
description = models.TextField(db_column='Description', blank=True, null=True)
created_at = models.DateTimeField(db_column='Created_at')
class table_name_2(models.Model):
title = models.TextField(db_column='Title', blank=True, null=True)
url = models.CharField(db_column='Url', unique=True, max_length=250, blank=True,
null=True)
description = models.TextField(db_column='Description', blank=True, null=True)
created_at = models.DateTimeField(db_column='Created_at')
and so on...
And i only want to make 1 class that includes all those tables that have same structure and call it when i choose the table from the PrimaryTable.
I don't want to use "python manage.py inspectdb > models.py" every time i create a table. I want to have access to the new created table instantly when i create it.
You can define your model fields as dict:
fields = dict(
title = models.TextField(db_column='Title', blank=True, null=True),
url = models.CharField(db_column='Url', unique=True, max_length=250, blank=True, null=True),
description = models.TextField(db_column='Description', blank=True, null=True),
created_at = models.DateTimeField(db_column='Created_at'),
)
Then you can dynamicly create and run migration for it:
from django.db import connection, migrations, models
from django.db.migrations.executor import MigrationExecutor
def create_table(table_name, model_fields, app_label):
class Migration(migrations.Migration):
initial = True
dependencies = []
operations = [
migrations.CreateModel(
name=table_name,
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
] + [(k, field) for k,field in model_fields.items()],
options={
'db_table': table_name,
},
),
]
executor = MigrationExecutor(connection)
migration = Migration(table_name, app_label)
with connection.schema_editor(atomic=True) as schema_editor:
migration.apply(executor._create_project_state(), schema_editor)
Then you can use dynamic model creation to access data in tables:
from django.db import models
def create_model(name, fields=None, app_label=None, module='', options=None, admin_opts=None):
"""
Create specified model
"""
class Meta:
db_table = name
if app_label:
# app_label must be set using the Meta inner class
setattr(Meta, 'app_label', app_label)
# Update Meta with any options that were provided
if options is not None:
for key, value in options.iteritems():
setattr(Meta, key, value)
# Set up a dictionary to simulate declarations within a class
attrs = {'__module__': module, 'Meta': Meta}
# Add in any fields that were provided
if fields:
attrs.update(fields)
# Create the class, which automatically triggers ModelBase processing
model = type(name, (models.Model,), attrs)
return model
I hope you will get general idea. I took code from project that uses Django 2 (similar code is used to create tables per uploaded CSV file, columns and name of each uploaded CSV is stored in table which is similar to your PrimaryTable).
You can simplify things by keeping all of the data with the same structure in one table. You can use admin filters and custom manager methods to focus on one type of information at a time, which will provide the same functionality as separate tables.
class Information(models.Model):
name = models.CharField(db_column='Name', unique=True, max_length=100)
date = models.CharField(db_column='Date', max_length=100)
information_type = models.ForeignKey(InformationType, related_name='information_records')
def __str__(self):
return self.name
class InformationType(models.Model):
title = models.TextField(db_column='Title', blank=True, null=True)
url = models.CharField(db_column='Url', unique=True, max_length=250, blank=True,
null=True)
description = models.TextField(db_column='Description', blank=True, null=True)
created_at = models.DateTimeField(db_column='Created_at')
def __str__(self):
return self.title
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With