Getting Started with Django: A Practical Q&A
By — min read
<p>Django has earned a loyal following among developers who value clarity and documentation over guesswork. Whether you’re building a side project or a full-scale app, Django’s philosophy of “explicit is better than implicit” can save you hours of head-scratching, especially if you set a project aside for months. Below are common questions from new Django users, answered with real-world examples and tips drawn from experience.</p>
<h2 id="why-django-over-rails">Why did you choose Django over Rails?</h2>
<p>I tried Rails in 2020, and while I loved the Ruby community, I found Rails’ “convention over configuration” approach made it hard for me to return to a project after a break. For instance, seeing <code>resources :topics</code> in <code>routes.rb</code> didn’t immediately tell me where topic routes were defined; I had to remember or look up Rails conventions. Django, on the other hand, feels more explicit. In my small Django project, I have five main files — <code>urls.py</code>, <code>models.py</code>, <code>views.py</code>, <code>admin.py</code>, and <code>tests.py</code> — and everything else (like HTML templates) is explicitly referenced from one of those files. This clarity means I can leave a project for months and pick it back up without re-learning the framework.</p><figure style="margin:20px 0"><img src="https://picsum.photos/seed/730476679/800/450" alt="Getting Started with Django: A Practical Q&A" style="width:100%;height:auto;border-radius:8px" loading="lazy"><figcaption style="font-size:12px;color:#666;margin-top:5px"></figcaption></figure>
<h2 id="explicit-vs-magic">What makes Django feel more explicit and less “magical”?</h2>
<p>Django follows a “explicit is better than implicit” design. In Rails, many actions are handled behind the scenes based on naming conventions (e.g., a controller automatically knows which view to render). Django requires you to explicitly define URL patterns, views, and templates. For example, in <code>urls.py</code> you write <code>path('articles/', views.article_list)</code> — the connection between URL and view is crystal clear. Similarly, database queries in the ORM are built with method chaining that reads like plain English, and relationships between models are declared with field types like <code>ForeignKey</code> and <code>ManyToManyField</code>. This explicitness makes it easier to understand what your code does at a glance, especially when revisiting a project after a long gap.</p>
<h2 id="built-in-admin">How does Django’s built-in admin work and how can you customize it?</h2>
<p>Django’s admin interface is a powerful, ready-to-use dashboard for managing your application’s data. Once you define your models in <code>models.py</code>, you register them in <code>admin.py</code> using <code>admin.site.register()</code> or a custom <code>ModelAdmin</code> class. The admin automatically generates list views, detail forms, and search functionality. You can customize it by adding attributes like <code>list_display</code> (which columns to show), <code>search_fields</code> (which fields to search), and <code>ordering</code> (default sort order). You can also add custom methods, like a function that returns an image preview. All of this requires just a few lines of Python code, and the admin stays out of your way until you need it.</p>
<h2 id="admin-example">Can you give an example of customizing the admin interface?</h2>
<p>Sure! Here’s a snippet from one of my admin classes that customizes the list view for a <code>Zine</code> model:</p>
<pre><code>@admin.register(Zine)
class ZineAdmin(admin.ModelAdmin):
list_display = ["name", "publication_date", "free", "slug", "image_preview"]
search_fields = ["name", "slug"]
readonly_fields = ["image_preview"]
ordering = ["-publication_date"]</code></pre>
<p>This tells Django to display those five columns in the list table, enable search on name and slug, make the image preview field read-only in the edit form, and sort records by publication date descending. The <code>image_preview</code> is a custom method that returns an HTML image tag; you can define such methods in the admin class. This level of customization is straightforward and keeps your data management clean.</p>
<h2 id="orm-vs-raw-sql">What is your experience with Django’s ORM compared to writing raw SQL?</h2>
<p>I used to think ORMs were unnecessary because I enjoyed writing SQL directly. But Django’s ORM won me over by making complex queries readable and database-agnostic. For instance, to find all zines that have been ordered by a specific email, I can write:</p>
<pre><code>Zine.objects.exclude(product__order__email_hash=email_hash)</code></pre>
<p>This query joins five tables (zines, zine_products, products, order_products, orders) automatically, using the <code>__</code> syntax to traverse relationships. All I had to do was define <code>ManyToManyField</code> relationships between models. The ORM handles the SQL joins, keeps my code portable, and makes the intention clear. It also helps prevent SQL injection and reduces boilerplate. I still use raw SQL for very complex queries, but for 90% of cases, the ORM is faster and safer.</p>
<h2 id="join-syntax">How does Django represent joins in ORM queries?</h2>
<p>Django uses double underscores to “follow” relationships between models. In the example above, <code>product__order__email_hash</code> means: start from the current model, follow the <code>product</code> relationship, then follow the <code>order</code> relationship, and access the <code>email_hash</code> field. Each underscore pair represents a join across a ForeignKey or ManyToManyField. This syntax works across multiple levels and even supports filters like <code>product__order__created__gte=datetime.date(2023,1,1)</code>. It takes a bit of practice, but once you understand the pattern, you can write complex queries in a single line that would otherwise require raw SQL with multiple JOIN clauses. Django’s ORM also offers <code>select_related</code> and <code>prefetch_related</code> to optimize performance when you know you’ll access related data.</p>
<h2 id="main-files">What are the main files in a Django project besides settings?</h2>
<p>Beyond the <code>settings.py</code> file (which contains database config, installed apps, etc.), a typical Django app has five core files:</p>
<ul>
<li><strong><code>urls.py</code></strong> — defines URL patterns and maps them to views.</li>
<li><strong><code>models.py</code></strong> — defines the database schema using Python classes.</li>
<li><strong><code>views.py</code></strong> — contains the logic that processes requests and returns responses.</li>
<li><strong><code>admin.py</code></strong> — registers models with the admin interface and customizes its behavior.</li>
<li><strong><code>tests.py</code></strong> — houses unit tests for your app.</li>
</ul>
<p>Other files may include <code>forms.py</code> for form definitions, <code>serializers.py</code> if you’re using Django REST Framework, and template files (HTML). But the core logic lives in those five files, making it easy for anyone to jump in and understand the app’s structure.</p>
Tags: