logo
Blog Image

Lessons From Building a Django Backend With a Small Team

5 min read

By Shobit Sharma

Share:

The Reality of Backend Development in a Team

Over the last month, we worked on a Django-based backend where multiple developers were building features in parallel.

On paper, it sounds straightforward:

  • forms
  • APIs
  • authentication
  • file uploads
  • PostgreSQL
  • Docker deployment

But in reality, backend development in a team is not just about writing code.

It’s about coordination.
It’s about discipline.
And most importantly — it’s about understanding how everything connects.

This is not about one project.
This is about what actually happens when a real backend is built by multiple developers.


Backend Development Is Not Just Writing Views

At the beginning, it's easy to think backend work means:

  • write views
  • save data
  • return response

But very quickly, you realize it includes much more:

  • database schema design
  • model changes
  • migrations
  • validation
  • authentication
  • file handling
  • API structure
  • deployment
  • team workflow

The important realization:

One small change in a model is never just a model change.

It can affect:

  • database structure
  • migration history
  • production deployment
  • other developers' work

That’s when you understand:

  • Backend development is not just code
  • It is a system of connected decisions

Migrations Are Not Just Commands — They Are a Contract

At first, migrations feel like routine commands:

python manage.py makemigrations
python manage.py migrate

But they represent something deeper.

  • makemigrations → creates change history
  • migrate → applies that history to the database

Key learning:

  •  Migrations are the contract between your code and your database

Golden Rule:

Development = makemigrations + migrate  
Production = migrate only

Production should never generate migrations.
It should only apply what is already reviewed and committed.


Shared Development Databases Are Powerful — And Risky

Working with a shared development database makes collaboration easier.

Everyone works on the same dataset.
Testing becomes realistic.

But it introduces a new kind of problem.

 A simple scenario:

  • Developer A creates a new table
  • Runs migration on shared DB
  • Table now exists

Meanwhile:

  • Developer B hasn’t pulled the latest code
  • But sees the new table in DB

Now confusion starts.


What We Learned

  • Always commit migration files with model changes
  • Pull latest code before creating new migrations
  • Communicate before changing shared structures
  • Avoid experiments on shared DB

A shared DB is useful — but without discipline, it becomes chaos.


Migration Conflicts Are Inevitable

When multiple developers work on models, conflicts are not a bug — they are expected.

Example:

  • Two developers create migrations with same number
  • Both are valid
  • But Django doesn’t know the order

   The solution:

python manage.py makemigrations --merge

     The real lesson:

  • Migration files are history
  • Don’t rename, delete, or “fix” them randomly

Handle them carefully, like version control for your database.


Working With Existing Databases Requires Strategy

Not every project starts clean.

Sometimes:

  • Tables already exist
  • Data is already important
  • No proper migration history exists

Deleting everything is not an option.


   The Practical Approach

Treat the current database as a baseline:

  • Keep existing tables
  • Keep existing data
  • Align models with DB
  • Start proper migrations from now

This allows you to move from:

  • unstructured development
  • to controlled, trackable backend evolution

Production Is Not a Playground

This is one of the most important lessons.

Production must be predictable.

      That means:

  • No makemigrations in production
  • No manual table creation
  • No copying data manually
  • No experimental changes

A Safe Deployment Flow

Pull approved branch  
Apply migrations  
Restart or rebuild service  
Verify workflows  

If Docker is involved:

  •  Code changes usually require rebuilding the container

   Branching Strategy Is Not Optional

When multiple developers are involved, branching becomes critical.

    A clean flow:

production  
   ↓  
development  
   ↓  
feature branches  
   ↓  
pull request  
   ↓  
testing  
   ↓  
merge to production  

      Naming matters too:

feature/rahul/inspection-upload  
fix/sneha/duplicate-check  
update/amit/report-flow  

Clear names reduce confusion during reviews and deployment.


  Commit Messages Decide Your Future Pain

At the moment, writing:

update  
changes  
final  

feels fine.

Later, it becomes a nightmare.


   What Works Better  

Add duplicate check for village records  
Fix file deletion during edit flow  
Update asset valuation calculation  

Good commits help in:

  • debugging
  • rollback
  • code review
  • tracking changes

      APIs Should Be Predictable

Even in server-rendered apps, APIs exist.

And inconsistency creates unnecessary frontend problems.


     A Simple Rule

Success:

return JsonResponse({"success": True, "data": payload})

Error:

return JsonResponse({"success": False, "error": "village is required"}, status=400)
  • Consistency reduces confusion. Always.

  File Upload Is Not Just Upload

Saving a file is just the beginning.

A complete flow includes:

  • upload
  • multiple files
  • preview/download
  • edit without losing data
  • duplicate handling
  • deletion from DB
  • deletion from storage

      Common Mistakes

  • Deleting DB record but not file
  • Replacing files unintentionally during edit

File handling must be tested across full lifecycle, not just upload.


    Environment Separation Prevents Mistakes

Mixing local and production behavior is dangerous.


    Clear Separation

Local:

  • runserver
  • makemigrations
  • migrate
  • testing

Production:

  • pull code
  • migrate
  • restart/rebuild
  • verify

This prevents accidental production damage.


     Backend Is Not Just Code — It Is Process

This is the biggest realization.

A good backend answers:

  • Where do I start work?
  • When do I create migrations?
  • Who runs migrations?
  • What happens during conflicts?
  • What goes to production?

     If unclear:

  • mistakes multiply
  • progress slows

     If clear:

  • development becomes smooth

   Final Thought

At first, process feels like overhead.

But over time, you realize:

  • Process is what keeps the system stable

     The Real Takeaway

Backend development is code + database + process

If all three are handled properly:

  • development becomes faster
  • deployments become safer
  • and the system becomes easier to scale
Share:

Related Articles

Image

Unlock Exclusive Content and Stay updated.

Subscribe today!

Interesting content are in store for you.

What are you interested to know more about?