<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Vinu Kaveesha on Medium]]></title>
        <description><![CDATA[Stories by Vinu Kaveesha on Medium]]></description>
        <link>https://medium.com/@vinukaveesha?source=rss-45266ce5d2ba------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*lAcIvtamUVXesek3</url>
            <title>Stories by Vinu Kaveesha on Medium</title>
            <link>https://medium.com/@vinukaveesha?source=rss-45266ce5d2ba------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 01:05:24 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@vinukaveesha/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Django Dynamic Model Creation]]></title>
            <link>https://medium.com/@vinukaveesha/django-dynamic-model-creation-df88358f7e88?source=rss-45266ce5d2ba------2</link>
            <guid isPermaLink="false">https://medium.com/p/df88358f7e88</guid>
            <dc:creator><![CDATA[Vinu Kaveesha]]></dc:creator>
            <pubDate>Wed, 26 Mar 2025 14:33:22 GMT</pubDate>
            <atom:updated>2025-08-15T04:26:35.966Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HVKOLLX7wprRbHTl2IPDcQ.png" /></figure><h3>Why Create Models Dynamically?</h3><p>Creating models dynamically can be helpful in situations where the database schema is not known at development time, or if it can change during runtime.</p><p>Django allows us to define and manipulate database tables at runtime, which is quite different from the traditional approach of defining models statically in the code. This can be particularly useful for applications that dynamically adapt to varying database schemas based on external conditions or user inputs.</p><h3>Implementation of Dynamic Models</h3><p>In Django, models are usually defined as classes that inherit from django.db.models.Model, where each class represents a table in the database.</p><p>For a static model example in models.py</p><pre>from django.db import models.Model<br><br>class Employee(models.Model):<br>  first_name = models.CharField(max_length=100)<br>  last_name = models.CharField(max_length=100)<br>  email = models.EmailField(unique=True)<br>  date_joined = models.DateTimeField(auto_now_add=True)<br><br>  def __str__(self):<br>   return f&quot;{self.first_name} {self.last_name}&quot;</pre><p>However, dynamic models are created at runtime using Python’s type function instead of being written in the models.py file. This allows models to be generated programmatically based on the database structure.</p><p>The type() function is commonly used to return the type of an object, but it can also be used to create new types dynamically. The syntax for type() when used to create classes is</p><p>type(classname, superclasses, attributes_dict)</p><ul><li><strong>classname</strong> — string defining the class name</li><li><strong>superclasses — </strong>a tuple defining the parent classes from which the new class inherits.</li><li><strong>attributes_dict </strong>— a dictionary containing the attributes and methods of the class, where keys are attribute/method names and values are attribute values or method functions.</li></ul><p>These are the only steps you need to follow.</p><ol><li>First, we need to fetch the table details from the database dynamically,<br>(Here I use PostgreSQL and Oracle databases)</li></ol><p>PostgreSQL has an information schema consisting of a set of views that contain information about the objects defined in the database, such asinformation_schema.tables, which provides table names and other details. As well, Oracle has a view namedall_tables, which provides table names and other details.</p><pre># app_name/models.py<br>from django.db import connections<br>from django.conf import settings<br><br>def get_tables(db_alias, schema_name):<br>    &quot;&quot;&quot;Retrieves table names from the given database schema.&quot;&quot;&quot;<br>    connection = connections[db_alias]<br>    with connection.cursor() as cursor:<br>        if db_alias in settings.ORACLE_DB_LIST:<br>            cursor.execute(f&quot;SELECT table_name FROM all_tables WHERE owner = &#39;{schema_name}&#39;&quot;)<br>        elif db_alias in settings.POSTGRESQL_DB_LIST:<br>            cursor.execute(f&quot;SELECT table_name FROM information_schema.tables WHERE table_schema = &#39;{schema_name.lower()}&#39;&quot;)<br>        return [row[0] for row in cursor.fetchall()]</pre><p>2. Then fetch the column details of each table for use in Django fields,</p><pre># app_name/models.py<br>def get_column_details(db_alias, schema_name, table_name):<br>    &quot;&quot;&quot;Fetches column names and types from the database table.&quot;&quot;&quot;<br>    connection = connections[db_alias]<br>    with connection.cursor() as cursor:<br>        if db_alias in settings.ORACLE_DB_LIST:<br>            cursor.execute(f&quot;SELECT COLUMN_NAME, DATA_TYPE FROM all_tab_columns WHERE table_name=UPPER(&#39;{table_name}&#39;) AND owner = UPPER(&#39;{schema_name}&#39;)&quot;)<br>        elif db_alias in settings.POSTGRESQL_DB_LIST:<br>            cursor.execute(f&quot;SELECT column_name, data_type FROM information_schema.columns WHERE table_schema = &#39;{schema_name.lower()}&#39; AND table_name = &#39;{table_name.lower()}&#39;&quot;)<br>        return cursor.fetchall()</pre><p>3. Mapping database data types to Django fields,</p><pre># app_name/models.py<br>from django.db import models<br><br>def map_data_type_to_django_field(data_type):<br>    &quot;&quot;&quot;Maps database column types to Django model fields.&quot;&quot;&quot;<br>    mapping = {<br>        &#39;VARCHAR2&#39;: models.CharField,<br>        &#39;CHAR&#39;: models.CharField,<br>        &#39;TEXT&#39;: models.TextField,<br>        &#39;INTEGER&#39;: models.IntegerField,<br>        &#39;BIGINT&#39;: models.BigIntegerField,<br>        &#39;SMALLINT&#39;: models.SmallIntegerField,<br>        &#39;FLOAT&#39;: models.FloatField,<br>        &#39;DOUBLE&#39;: models.FloatField,<br>        &#39;DECIMAL&#39;: models.DecimalField, <br>        &#39;NUMERIC&#39;: models.DecimalField,<br>        &#39;DATE&#39;: models.DateField,<br>        &#39;TIMESTAMP&#39;: models.DateTimeField,<br>        &#39;BOOLEAN&#39;: models.BooleanField<br>    }<br>    return mapping.get(data_type.upper(), models.CharField)</pre><p>4. Retrieving the primary key for each table,</p><pre># app_name/models.py<br>def get_primary_key(db_alias, schema_name, table_name):<br>    &quot;&quot;&quot;Retrieves the primary key of a database table.&quot;&quot;&quot;<br>    connection = connections[db_alias]<br>    with connection.cursor() as cursor:<br>        if db_alias in settings.ORACLE_DB_LIST:<br>            cursor.execute(f&quot;&quot;&quot;<br>                SELECT cols.column_name<br>                FROM all_constraints cons, all_cons_columns cols<br>                WHERE cons.constraint_type = &#39;P&#39;<br>                AND cons.constraint_name = cols.constraint_name<br>                AND cons.owner = UPPER(&#39;{schema_name}&#39;)<br>                AND cols.table_name = UPPER(&#39;{table_name}&#39;)<br>            &quot;&quot;&quot;)<br>        elif db_alias in settings.POSTGRESQL_DB_LIST:<br>            cursor.execute(f&quot;&quot;&quot;<br>                SELECT kcu.column_name<br>                FROM information_schema.table_constraints AS tc<br>                JOIN information_schema.key_column_usage AS kcu<br>                ON tc.constraint_name = kcu.constraint_name<br>                WHERE tc.table_schema = &#39;{schema_name.lower()}&#39;<br>                AND tc.table_name = &#39;{table_name.lower()}&#39;<br>                AND tc.constraint_type = &#39;PRIMARY KEY&#39;<br>            &quot;&quot;&quot;)<br>        result = cursor.fetchall()<br>        return result[0][0] if result else None</pre><p><strong>The Moment You’ve Been Waiting For</strong></p><p>5. Creating the dynamic model</p><pre># app_name/models.py<br>from django.apps import apps<br>from django.core.exceptions import ImproperlyConfigured<br><br>def create_dynamic_model(table_name, db_alias, schema_name, app_label):<br>    &quot;&quot;&quot;Dynamically creates a Django model from a database table.&quot;&quot;&quot;<br>    columns = get_column_details(db_alias, schema_name, table_name)<br>    primary_key = get_primary_key(db_alias, schema_name, table_name)<br><br>    fields = {<br>        &#39;__module__&#39;: __name__,<br>        &#39;Meta&#39;: type(&#39;Meta&#39;, (), {<br>            &#39;managed&#39;: False,<br>            &#39;db_table&#39;: f&#39;&quot;{schema_name}&quot;.&quot;{table_name}&quot;&#39;,<br>            &#39;app_label&#39;: app_label,<br>        }),<br>    }<br><br>    # If there is no primary key for the table <br>    if not primary_key:<br>        fields[&#39;id&#39;] = models.AutoField(primary_key=True)<br><br>    for column, data_type in columns:<br>        field_class = map_data_type_to_django_field(data_type)<br>        field_params = {&#39;max_length&#39;: 255} if issubclass(field_class, models.CharField) else {}<br>        <br>        if issubclass(field_class, models.DecimalField):<br>            field_params[&#39;max_digits&#39;] = 10<br>            field_params[&#39;decimal_places&#39;] = 2<br><br>        fields[column] = field_class(primary_key=(column == primary_key), **field_params)<br><br>    model_name = table_name.replace(&#39; &#39;, &#39;_&#39;).replace(&#39;.&#39;, &#39;_&#39;).capitalize()<br>    DynamicModel = type(model_name, (models.Model,), fields)<br><br>    # Registers the dynamically created model in the Django admin interface.<br>    register_dynamic_model(DynamicModel, db_alias)<br><br>    return DynamicModel</pre><p>6. Registering the dynamic model in Django admin</p><pre># app_name/admin.py<br>from django.contrib import admin<br>from django.db import models<br>from django.apps import apps<br><br>def register_dynamic_model(model, db_alias):<br>   <br>    class DynamicAdmin(admin.ModelAdmin):<br>        &quot;&quot;&quot;Custom Admin class for dynamic models.&quot;&quot;&quot;<br>        <br>        model._meta.db_table = support_database(model._meta.db_table)<br><br>        def get_queryset(self, request):<br>            return super().get_queryset(request).using(db_alias)<br><br>        # Auto-generate list display and search fields based on model fields<br>        list_display = [field.name for field in model._meta.fields if hasattr(field, &#39;name&#39;)]<br>        search_fields = [field.name for field in model._meta.fields if isinstance(field, models.CharField) and hasattr(field, &#39;name&#39;)]<br>        list_filter = [field.name for field in model._meta.fields if isinstance(field, models.BooleanField) and hasattr(field, &#39;name&#39;)]<br><br>    # Register the model with the specified admin site<br>    admin_site.register(model, DynamicAdmin)</pre><p>7. Setting AppConfig for Dynamic Models</p><pre># app_name/apps.py<br>from django.apps import AppConfig<br><br>class DynamicModelAppConfig(AppConfig):<br>    default_auto_field = &#39;django.db.models.BigAutoField&#39;<br>   <br>    db_alias = &#39;your_db_alias&#39;<br>    schema_name = &#39;your_schema_name&#39;<br>    table_name = &#39;your_table_name&#39;<br><br>    # Generate a dynamic base name for the app<br>    base_name = f&quot;{db_alias.title().replace(&#39; &#39;, &#39;&#39;)}.{db_alias.title().replace(&#39; &#39;, &#39;&#39;)}_{schema_name.title().replace(&#39; &#39;, &#39;&#39;)}&quot;<br>    name = f&quot;{base_name}&quot;<br><br>    # Label for the app, typically used for model registration<br>    label = f&quot;{db_alias.lower()}_{schema_name.lower()}&quot;.strip()<br><br>    def ready(self):<br>        from .models import create_dynamic_models<br>        create_dynamic_models(self.table_name, self.db_alias, self.schema_name, self.label)</pre><p>Dynamic model creation in Django is a powerful technique that allows applications to adapt to evolving database structures without requiring manual code updates. By using <strong>Python’s type() function and Django’s ORM</strong>, we can generate models on the fly, making our applications more flexible and scalable.</p><p>This approach is particularly useful for systems that interact with multiple databases, deal with user-defined schemas, or require real-time adaptability. However, with great power comes great responsibility — always ensure that dynamically generated models align with your security, performance, and maintainability goals.</p><p>Whether you’re working with PostgreSQL, Oracle, or any other database, dynamically creating models unlocks a world of possibilities. Experiment with this technique, refine it to your needs, and take your Django projects to the next level!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=df88358f7e88" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>