Importing Django Models to PormG
This tutorial provides a guide on how to migrate Django models to PormG using the import_models_from_django
function.
Overview
The import_models_from_django
function allows you to seamlessly convert Django model definitions from Python models.py
files into PormG-compatible Julia models. This is particularly useful when:
- Migrating existing Django projects to Julia
- Maintaining consistency between Django and Julia models
- Quickly prototyping Julia models based on existing Django schemas
- Converting legacy Django models for use in Julia applications
- Create a ETL pipeline for data processing in Julia for a Django APP (my case)
Function Signature
import_models_from_django(
model_py_string::String;
db::String = DB_PATH,
force_replace::Bool = false,
ignore_table::Vector{String} = postgres_ignore_table,
file::String = "automatic_models.jl",
autofields_ignore::Vector{String} = ["Manager"],
parameters_ignore::Vector{String} = ["help_text"]
)
Basic Usage
Step 1: Prepare Your Django Models File
Ensure your Django models.py
file follows standard Django conventions:
# models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class Category(models.Model):
name = models.CharField(max_length=100, unique=True)
description = models.TextField(blank=True)
created_at = models.DateTimeField(auto_now_add=True)
class User(AbstractUser):
email = models.EmailField(unique=True)
bio = models.TextField(max_length=500, blank=True)
birth_date = models.DateField(null=True, blank=True)
class Product(models.Model):
name = models.CharField(max_length=200)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
is_active = models.BooleanField(default=True)
created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
Step 2: Import Using File Path
using PormG.Migrations
import_models_from_django("/path/to/your/models.py")
Parameters Explained
Required Parameters
model_py_string::String
: The content of your Djangomodels.py
file. Can be:- File path to your
models.py
file - String content of the models file
- Output from
django_to_string(path)
- File path to your
Optional Parameters
db::String
: Database configuration key (default:DB_PATH
)import_models_from_django(content, db="production")
force_replace::Bool
: Overwrite existing model files (default:false
)import_models_from_django(content, force_replace=true)
ignore_table::Vector{String}
: Tables to skip during importimport_models_from_django(content, ignore_table=["auth_user", "django_migrations"])
file::String
: Output filename (default:"automatic_models.jl"
)import_models_from_django(content, file="my_models.jl")
autofields_ignore::Vector{String}
: Field types to ignore (default:["Manager"]
)import_models_from_django(content, autofields_ignore=["Manager", "CustomManager"])
parameters_ignore::Vector{String}
: Field parameters to ignore (default:["help_text"]
)import_models_from_django(content, parameters_ignore=["help_text", "verbose_name"])
Supported Django Fields
The function supports conversion of the following Django field types:
Text Fields
CharField
→CharField
TextField
→TextField
EmailField
→EmailField
Numeric Fields
IntegerField
→IntegerField
BigIntegerField
→BigIntegerField
FloatField
→FloatField
DecimalField
→DecimalField
Date/Time Fields
DateField
→DateField
DateTimeField
→DateTimeField
TimeField
→TimeField
Boolean Fields
BooleanField
→BooleanField
Relationship Fields
ForeignKey
→ForeignKey
OneToOneField
→OneToOneField
Special Fields
AutoField
→AutoField
ImageField
→ImageField
Field Mapping
Parameter Conversion
Django parameters are automatically converted to PormG equivalents:
Django Parameter | PormG Parameter | Notes |
---|---|---|
max_length | max_length | Direct mapping |
null=True | null=true | Boolean conversion |
blank=True | blank=true | Boolean conversion |
unique=True | unique=true | Boolean conversion |
default=value | default=value | Value conversion |
on_delete=CASCADE | on_delete=CASCADE | Direct mapping |
choices=[] | choices=() | List to tuple conversion |
⚠️ Important: CharField with Choices Syntax
When using CharField
with choices, PormG requires the choices to be defined inline for proper parsing. External variables are not supported.
# ✅ CORRECT - Use this pattern:
user_type = models.CharField(
default=3,
choices=((1,"Type 1"),(2,"Type 2"),(3,"Type 3"),(4,"Type 4"),(5,"Type 5")),
max_length=10
)
# ❌ INCORRECT - Don't use this pattern:
user_type_data=((1,"Type 1"),(2,"Type 2"),(3,"Type 3"),(4,"Type 4"),(5,"Type 5"))
user_type = models.CharField(
max_length=10,
choices=user_type_data
)
Key Requirements:
- Inline definition: Define choices directly in the field, not as external variables
- Tuple format: Use parentheses
()
for choices, not square brackets[]
- Tuple structure: Each choice must be a tuple
(value, display_name)
- Nested tuples: The entire choices parameter must be a tuple of tuples
- Parameter order: Place
default
beforechoices
for better parsing reliability
Automatic Additions
- Primary Key: If no primary key is defined,
id = Models.IDField()
is automatically added - AbstractUser: For models inheriting from
AbstractUser
, additional fields likedate_joined
are added
Limitations and Considerations
Current Limitations
- Field Types: Not all Django field types are supported
- Complex Relationships: ManyToManyField is not yet supported
- Custom Fields: Custom Django fields require manual conversion
- Metaclass Options: Model Meta options are not converted
- Methods: Model methods are not converted (only fields)
This will generate Julia models compatible with PormG that maintain the same structure and relationships as your original Django models.