Full Django Template Compatibility: URL Tags, Comparison Operators, and Auto-Serialization
Making Migration Effortless
One of djust's core promises is seamless migration from traditional Django. With v0.1.6, we've taken a major step forward by adding full support for Django's most commonly used template features. Your existing Django templates now work with djust's Rust rendering engine with minimal or no changes.
Let's explore the five key improvements that make this possible.
1. {% url %} Tag Support
Django's URL reversing is essential for maintainable templates. Previously, you had to manually resolve URLs in your views. Now, djust handles this automatically.
Before (workaround required):
# views.py - manual URL resolution
from django.urls import reverse
class MyView(LiveView):
def mount(self, request):
self.home_url = reverse('home')
self.profile_url = reverse('user_profile', kwargs={'username': 'john'})
After (just works):
<!-- template.html - standard Django syntax -->
<a href="{% url 'home' %}">Home</a>
<a href="{% url 'user_profile' username='john' %}">Profile</a>
<a href="{% url 'post_detail' post.slug %}">Read More</a>
djust now supports:
- Named URLs:
{% url 'view_name' %} - Positional arguments:
{% url 'post_detail' post.slug %} - Keyword arguments:
{% url 'search' category='tech' query='djust' %} - Variable assignment:
{% url 'home' as home_link %}
2. {% include %} Tag Fix
Template includes are fundamental to DRY template design. The previous version had issues resolving include paths when templates were in subdirectories. This is now fixed.
Before (broken with directories):
<!-- This failed if _header.html was in a different directory -->
{% include 'components/_header.html' %}
After (works correctly):
<!-- All your includes just work -->
{% include 'components/_header.html' %}
{% include 'partials/_sidebar.html' with user=request.user %}
{% include '_footer.html' only %}
The fix ensures template directories are properly passed to the Rust rendering engine, supporting both absolute and relative include paths.
3. urlencode Filter
Building URLs with dynamic content requires proper encoding. The new urlencode filter matches Django's behavior exactly.
<!-- Encode search queries -->
<a href="/search?q={{ query|urlencode }}">Search</a>
<!-- Build dynamic URLs safely -->
<a href="/tag/{{ tag_name|urlencode }}">{{ tag_name }}</a>
The filter properly encodes:
- Spaces as
%20 - Special characters like
&,=,? - Unicode characters (multi-byte UTF-8)
- Preserves safe characters: alphanumeric,
-,_,.,~
4. Comparison Operators in {% if %} Conditions
Numeric comparisons are now fully supported. Previously, you could only use equality checks. Now you can write natural conditional logic.
Before (limited to equality):
{% if count == 0 %}Empty{% endif %}
After (full comparison support):
{% if count > 0 %}
{{ count }} item{{ count|pluralize }}
{% endif %}
{% if price >= 100 %}
<span class="premium">Premium Product</span>
{% endif %}
{% if stock < 5 %}
<span class="warning">Low Stock!</span>
{% endif %}
{% if score <= threshold %}
<span class="alert">Below target</span>
{% endif %}
Supported operators:
- Greater than:
> - Less than:
< - Greater than or equal:
>= - Less than or equal:
<= - Equal:
==(already supported) - Not equal:
!=(already supported)
These work with integers, floats, and even cross-type comparisons (comparing an integer to a float).
5. Automatic Django Type Serialization
This is perhaps the most developer-friendly improvement. Django models often contain types that aren't natively JSON-serializable: datetime, Decimal, UUID, and file fields. Previously, you had to manually serialize these.
Before (manual serialization):
# views.py - tedious conversion
class OrderView(LiveView):
def mount(self, request):
order = Order.objects.get(pk=1)
self.created_at = order.created_at.isoformat()
self.total = float(order.total) # Decimal to float
self.order_id = str(order.uuid) # UUID to string
self.invoice_url = order.invoice.url if order.invoice else None
After (automatic):
# views.py - just pass the data
class OrderView(LiveView):
def mount(self, request):
self.order = Order.objects.get(pk=1)
<!-- template.html - use directly -->
<p>Order ID: {{ order.uuid }}</p>
<p>Created: {{ order.created_at|date:"F j, Y" }}</p>
<p>Total: ${{ order.total }}</p>
<a href="{{ order.invoice }}">Download Invoice</a>
djust now automatically serializes:
- datetime/date/time: ISO format strings
- Decimal: Float values
- UUID: String representation
- FieldFile/ImageField: URL string (or None if empty)
- Nested dicts and lists: Recursively processed
Migration Made Simple
These improvements mean your existing Django templates are more likely to "just work" with djust. The goal is zero friction migration: install djust, point it at your templates, and enjoy 10-100x faster rendering.
Try it today:
pip install djust==0.1.6
Check out our documentation for the complete list of supported template tags and filters, and join our GitHub community to report any compatibility issues.
Related Posts
Faster Templates, Smarter Hydration: Performance Optimizations in djust 0.1.6
djust 0.1.6 introduces AST optimization for 5-15% faster rendering, lazy hydration for 20-40% memory reduction, TurboNav integration, and improved whitespace preservation.
Security-First Development: How djust Protects Your Application by Default
djust now includes built-in security utilities, automated vulnerability scanning, and pre-commit hooks to help you build secure applications from day one. Here's what's new in PR #40.
Introducing djust: Phoenix LiveView for Django
We are excited to announce djust, a framework that brings Phoenix LiveView-style reactive server-side rendering to Django. Build real-time, interactive web applications with Python - no JavaScript required.