Django comparison

Route, view, form, ORM and security equivalences.

● ● ●
-- Django (urls.py)
urlpatterns = [
    path("articles/",      views.article_list, name="article_list"),
    path("articles/<id>/", views.article_detail, name="article_detail"),
]

-- Runique (url.rs)
urlpatterns! {
    "/articles"      => view! { article_list },   name = "article_list",
    "/articles/{id}" => view! { article_detail }, name = "article_detail",
}
-- Django (views.py)
def article_list(request):
    articles = Article.objects.all()
    return render(request, "articles.html", {"articles": articles})

-- Runique (views.rs)
pub async fn article_list(mut request: Request) -> AppResult<Response> {
    let db = request.engine.db.clone();
    let articles = Article::objects.all().all(&*db).await?;
    context_update!(request => { "articles" => &articles });
    request.render("articles.html")
}
-- Django (models.py)
class Article(models.Model):
    title   = models.CharField(max_length=255)
    content = models.TextField()
    author  = models.ForeignKey(User, on_delete=models.CASCADE)

-- Runique (entities/article.rs)
model! {
    Article,
    table: "article",
    pk: id => i32,
    fields: {
        title:     text [max_length: 255, required],
        content:   text [required],
        author_id: i32 [required],
    },
    relations: {
        belongs_to: user via author_id [cascade],
    }
}

impl_objects!(Article);
-- Django (forms.py)
if form.is_valid():
    title = form.cleaned_data["title"]

-- Runique (views.rs)
if form.is_valid().await {
    // Simplified direct access
    let title = form.cleaned_string("title").unwrap_or_default();
    
    // Or whitelist (POST > URL)
    let search = form.cleaned_string("search").unwrap_or_default();
}
-- Django (settings.py)
SECRET_KEY = "..."
DATABASES  = { "default": { "ENGINE": "django.db.backends.postgresql", ... } }
DEBUG      = True

-- Runique (.env + main.rs)
SECRET_KEY=...
DATABASE_URL=postgres://user:pass@localhost/db
DEBUG=true

// main.rs
let config = RuniqueConfig::from_env();
let db     = DatabaseConfig::from_env()?.build().connect().await?;