Django Best Practices

Sudip Kafle

@kaflesudip

A web framework for perfectionists with deadline

Why Django?

Fast

Batteries included

Secure

Community

We ♥ Python

I am a beginner

MVC MTV Architecture

Models -> Models

Views -> Templates

Controller -> Entire Framework

Browser

Views

Models

Templates

URLs

http://flipkarma.com/project/corporate-decision-support-system-for-telecommunic/

'^project/(?P<slug>[-\w]+)/$'
class ProjectDetailView(DetailView):
class Project(models.Model):
select * from Project where slug='...'
Raw Data
Data(objects)
Data + other..
HTML

URLS

Maps regular expressions to Python functions.

'/project/[0-9]+'

why not  '^project/{id}/$'

Never do '/project/(.+)'

Models

# product/models.py


class Product(models.Model):
    name = models.Charfield()
    description = models.StringField()
    price = models.FloatField()
    category = models.ForeignKeyField(subject)

    def get_cheapest(self):
        .........................


+---------------------+--------------+------
| Field               | Type         | Key |
+---------------------+--------------+-----|
| id                  | int(11)      | PRI |
| name                | varchar(300) |     |
| description         | longtext     |     |
| price               | float        |     |
| category_id         | int(11)      | MUL |
+---------------------+--------------+-----+

Most of the business Logic reside in models

Views

Gets the data from models and sends it to the templates

No business logic

from .models import Product

def product(request, id):
    product_object = Product.objects.get(id=id)
    return render_to_response("products.html", {"product": product_object})

Templates

HTML + some templating languages.

<!-- product.html -->

<!DOCTYPE html>
<html lang="en">
.............
<body>

  <h1>{{product.name}}</h1>

  {% if product.description %}
    {{ product.description }}
  {% endif %}
  
</body>
</html>
<!-- product.html -->

<!DOCTYPE html>
<html lang="en">
.............
<body>

  <h1>Nike Shoes</h1>

  The shoes are really awesome
  priced at ...
  
</body>
</html>



# at models
def price_in_dollar(self, conversion_rate):
    return (self.price) / conversion_rate


# at views
price_in_dollar = product.price_in_dollar(101)


# at templates
Price in $: {{price_in_dollar}}
  1. Fat models
  2. Thin views
  3. Dumb templates

Apps


|   |   -- project
|   |       |-- app1
|   |       |   |-- __init__.py
|   |       |   |-- admin.py
|   |       |   |-- forms.py
|   |       |   |-- models.py
|   |       |   |-- tests.py
|   |       |   `-- urls.py
|   |       |-- app2
|   |       |   |-- __init__.py
|   |       |   |-- admin.py
|   |       |   |-- forms.py
|   |       |   |-- models.py
|   |       |   `-- urls.py
|   |       |-- project
|   |       |   |-- __init__.py
|   |       |   |-- settings.py
|   |       |   |-- urls.py
|   |       |   `-- wsgi.py
|   |       |-- manage.py
|   |       |-- static
|   |       |-- templates

Golden Rule for App Design

Design app that does one thing

 

  1. Try to explain what your app does in One sentence
  2. If you have 'and' in the sentence,
  3. Break it into two or more apps
  4. My app provides the ability to manage user accounts and upload videos.

Mistakes as Beginners

Don't mess up with settings.py

  1. Don't change STATIC settings. The defaults work on development environment without collectstatic.
  2. TEMPLATE_DIR, DATABASES and INSTALLED_APPS are to be changed.
  3. Windows style back slash - 'project\app\..'
  4. Use - 'project/app/...

Don't be afraid to create multiple apps

One App for the complete project will make it painful later

Leverage the power of forms.py

Don't hardcode the urls

Bad:

<a href="/product/{{id}}">......</a>

Good:

<a href="{% url 'product_page' id %}"....</a>

Prefer reverse in views.

reverse('product_page', args=(id,))

Don't mess up with security

  1. Avoid csrf_exempt in most cases
  2. Avoid {{ | safe }} filter in templates
  3. Don't trust user's data.

Final Tips

  1. Use Virtualenv
  2. Use Class Based Views
  3. Django Debug Toolbar
  4. iPython / bPython
  5. API's - Django Rest Framework
  6. Don't ignore tests.
  7. Use Fabric, Ansible or chef for deployment
  8. Master Python, data structures ...

Twitter / fb/ linkedin/ G+: @kaflesudip

meroanswer.com

Sudip Kafle

flipkarma.com

sudip@phunka.com

CTO and CoFounder at Phunka Technogies

Django Best Practices

By Sudip Kafle

Django Best Practices

  • 5,339