Entendendo Django

Agenda

  • Entendendo Projeto
  • Entendendo Apps
  • Adicionando Apps no Projeto

Projeto

"Projeto" é como Django chama a base do sistema.

Criado com django-admin startproject [PROJECT].

Projeto: startproject


.
├── exemplo
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py
                    

manage.py vira o gerenciador do projeto.

Projeto > App

Dentro do projeto, para criar um app:

python manage.py startapp [app]

Projeto > App


.
├── exemplo
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── settings.py
│   ├── settings.pyc
│   ├── urls.py
│   └── wsgi.py
├── manage.py
└── products
    ├── admin.py
    ├── __init__.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── tests.py
    └── views.py
                    

Projeto > App > models.py

Definição do banco de dados para o app.


class Product(models.Model):

    """Product information"""

    name = models.CharField(max_length=40)
                    

Projeto > App > admin.py

Definição do admin (ou não) dos models.


class ProductAdmin(admin.ModelAdmin):
    pass

admin.site.register(Product, ProductAdmin)
                    

Projeto > App > forms.py

Definição de formulários/formulários baseados em models.


class ProductForm(forms.Form):
    name = forms.CharField(label='Your name', max_length=40)
                    

class ProductForm(ModelForm):
    class Meta:
        model = Product
                    

Projeto > App > views.py

Views do app.


def get_product(request, product_id):
    if request.method == 'GET':
        product = get_object_or_404(Product, pk=product_id)
        return render(request, 
                      'product_info.html',
                      {'product': product})
    else:
        return render(request, 
                      'invalid.html',
                      {'reason': 'Can\'t create products yet'})
                    

Projeto > App > templates/product_info.html

Na verdade, todos os templates da app ficam em templates.


{% extends 'base.html' %}
  • Product name: {{ product.name }}

O base.html pode estar no templates do projeto.

Projeto > App > urls.py

URLs internas do app.


from . import views

urlpatterns = [
    url(r'^(?P<product_id>[0-9]+)/$', views.get_product, name='get'),

]
                    

App completa!

... só que o Django ainda não sabe que ela existe.

Projeto > settings.py


[...]
INSTALLED_APPS = (
    [...]
    'products',
    [...]
)
                    

Agora o Django sabe que a App existe!

Só não sabe como chegar lá porque faltam as URLs.

Projeto > urls.py


[...]
urlpatterns = [
    [...]
    url(r'/products', include('products')),
    [...]
]
                    

Agora funciona como esperado:

  • Request de um browser chega no Django;
  • Consulta o urls.py base do projeto para encontrar o que será executado;
  • Consulta o urls.py da app (no caso) para encontrar a view que será executada;
  • Encontra a view dentro da app, que busca as informações no model;
  • Renderiza o template;
  • Retorna o template renderizado para o usuário.
Go deeper

Relationships

Projeto > App > models.py


class Product(models.Model):

    """Product information"""

    name = models.CharField(max_length=40)
    price = models.DecimalField(max_digits=6, decimal_places=2)


class Order(models.Model):

    """An order."""

    products = models.ManyToManyField(Product)
                    

Inserts


product = Product(name='fruit')
order = Order()
order.products.add(product)
product.save()
order.save()
                    

Queries


all_products = Product.objects.all()
                    

fruit = Product.objects.get(pk=1)
fruit = Product.objects.get(name='fruit')
                    

all_fruits = Order.objects.filter(products__name__like='fruit')
                    

Queries

get só pode retornar um elemento.

pk é uma variável mágica que aponta para o campo marcado como primary_key=True; se não houver um primary_key, o Django cria um IntegerField(auto_increment=True).