"Projeto" é como Django chama a base do sistema.
Criado com django-admin startproject [PROJECT]
.
.
├── exemplo
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
manage.py
vira o gerenciador do projeto.
Dentro do projeto, para criar um app:
python manage.py startapp [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
Definição do banco de dados para o app.
class Product(models.Model):
"""Product information"""
name = models.CharField(max_length=40)
Definição do admin (ou não) dos models.
class ProductAdmin(admin.ModelAdmin):
pass
admin.site.register(Product, ProductAdmin)
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
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'})
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.
URLs internas do app.
from . import views
urlpatterns = [
url(r'^(?P<product_id>[0-9]+)/$', views.get_product, name='get'),
]
... só que o Django ainda não sabe que ela existe.
[...]
INSTALLED_APPS = (
[...]
'products',
[...]
)
Agora o Django sabe que a App existe!
Só não sabe como chegar lá porque faltam as URLs.
[...]
urlpatterns = [
[...]
url(r'/products', include('products')),
[...]
]
Agora funciona como esperado:
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)
product = Product(name='fruit')
order = Order()
order.products.add(product)
product.save()
order.save()
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')
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)
.
Quando é criada uma relação, o Django cria também uma relação reversa entre os models.
order = Order.objects.get(pk=1)
print order.products.all()
print Products.order_set.all()
O nome da relacionamento reverso pode ser alterado com
related_name
.
Fixtures são arquivos JSON que o Django consegue usar para preencher o banco de dados.
[
{
"pk": 1,
"model": "Products",
"fields": {
"name": "fruit"
}
}
]
Fixtures em testes se aplicam a suíte inteira.
Para definir que um teste usa fixtures, é usada a
variável fixtures
da classe.
class ProductTest(StaticLiveServerTestCase):
fixtures = ['products.json']
Para criação das tabelas de banco de dados, usa-se
python manage.py syncdb
.
Se houverem fixtures a serem carregadas, essas serão
injetadas no banco de dados durante o
syncdb
.
Signals (sinais) são eventos gerados dentro do Django para chamar funções de usuário em algumas condições (normalmente relacionadas com models).
from django.db.models.signals import pre_save
from django.dispatch import receiver
from models import Product
@receiver(post_save, sender=Product)
def after_saving_product(sender, instance, created, raw, using, update_fields):
# ...
save()
(None se forem todos).Funções especiais para templates para apresentação de valores.
Dentro do diretório templatetags
do App
ficam os módulos com os tags.
(Lembrar de colocar o arquivo __init__.py
para que
o Python detecte o diretório como um módulo).
def free(value):
if value == 0:
return _('Free')
return value
{{ product.price|free }}