Django Untangled
đź‘ť

Django Untangled

Tags
Django
Published
October 25, 2024
Last Updated
Last updated November 28, 2024
 
đź’ˇ
Note: This is a living document!

Intro

Django is an amazing framework. If you landed here, you probably already know that but let me try to highlight a few key functions.
Batteries included… yes, the famous tagline. It does indeed come with lots of incredible features built-in. You get authentication, a super-nice admin panel and an opinionated way to do certain things for your app or api.
However, Django does get tangled because in certain areas, there are no concise opinions. The community is divided on such things. I’ve tried to capture all such thoughts, comments and criticisms on this page.
 

Why Allauth's Headless Mode is the Optimal Choice for Authentication in Django

The tried and tested allauth package provides a headless mode, I recommend using that as it provides native integration with allauth and minimizes the code you need to override.
I’ve used dj-rest-auth and django-rest-auth in the past and both are fantastic packages however I try to minimize the use of extra dependencies and prefer keeping logic for one module contained. Using allauth’s headless mode allows you to do that.
 
 

Best Practices for Handling Operations on Django Model Properties

In Django, best practices for handling operations on model properties revolve around maintaining clean, maintainable, and efficient code. Here are the guidelines for what types of operations you can and cannot (or should not) put on a Django model's properties.

Operations You CAN Put on a Django Model's Properties

  1. Simple Computed Properties
      • Use Python's @property decorator for computed attributes based on other model fields.
      • Example:
        • class Product(models.Model): price = models.DecimalField(max_digits=10, decimal_places=2) discount = models.DecimalField(max_digits=10, decimal_places=2) @property def discounted_price(self): return self.price - self.discount
  1. Data Formatting
      • Add methods or properties to format data for display or use in templates.
      • Example:
        • @property def formatted_price(self): return f"${self.price:.2f}"
  1. Business Logic That Doesn't Change Database State
      • You can use methods or properties to encapsulate non-database-changing logic.
      • Example:
        • @property def is_eligible_for_free_shipping(self): return self.price > 100
  1. Foreign Key/Related Field Computations
      • Safely compute values based on related fields.
      • Example:
        • @property def total_order_price(self): return sum(item.price for item in self.order_items.all())
  1. Serialization Helpers
      • Add properties for structured or human-readable representations, e.g., full_name for combining first_name and last_name.

Operations You CANNOT/SHOULD NOT Put on a Django Model's Properties

  1. Database Queries in Properties
      • Avoid making database queries within properties, especially in loops or iterative logic, as they can lead to inefficient queries (N+1 problem).
      • Example (Bad Practice):
        • @property def expensive_property(self): return self.related_set.count() # Avoid if accessed frequently
      • Better Alternative: Use annotate() or prefetch_related() in your query to calculate related data at the database level.
  1. State-Changing Operations
      • Avoid modifying or saving data in a property method. Properties should remain read-only.
      • Example (Bad Practice):
        • @property def update_status(self): self.status = 'completed' # Don't do this self.save()
  1. Long or Complex Logic
      • Properties should remain concise and focused. Use helper methods or utility classes for complex logic.
      • Example:
        • def calculate_complex_value(self): # Perform complex operations here pass
  1. External API Calls
      • Avoid embedding API calls or any external dependencies inside properties. This can slow down your application and make debugging harder.
  1. Error-Prone or Unintended Mutations
      • Avoid mutable state within properties, as it can lead to bugs and unintended side effects.