Você está na página 1de 7

LOG IN

SIGN UP

Main menu
Articles Resources Downloads

Community

An introduction to the Django ORM


Learn how to use the Python web framework's object-relational
mapper to interact with your database, just like you would with
SQL.
24 Nov 2017 |
Katie McLaughlin (/users/glasnt) 
| 338
| 3 comments

Image by : Christian Holmér. Modified by Opensource.com. CC BY-SA 4.0

Você já deve ter ouvido falar de Django (https://www.djangoproject.com/), a estrutura


web python para "perfeccionistas com prazos". É aquele com o pônei bonito.
(http://www.djangopony.com/)

Uma das características mais poderosas do Django é o Object-Relational Mapper


(ORM), que permite interagir com seu banco de dados, como faria com o SQL. Na
verdade, o ORM de Django é apenas uma maneira pythonical de criar SQL para
consultar e manipular seu banco de dados e obter resultados de uma forma pythonic.
Bem, eu digo apenas uma maneira, mas é realmente engenharia muito inteligente que
aproveita algumas das partes mais complexas do Python para tornar a vida dos
desenvolvedores mais fácil.

Antes de começarmos a investigar como o ORM funciona, precisamos de um banco de


dados para manipular. Como em qualquer banco de dados relacional, precisamos definir
um monte de tabelas e seus relacionamentos (ou seja, a forma como eles se
relacionam). Vamos usar algo familiar. Por exemplo, digamos que queremos modelar um
blog que tenha posts e autores de blogs. Um autor tem um nome. Um autor pode ter
muitos posts no blog. Um post no blog pode ter muitos autores e tem um título, conteúdo
e uma data publicada.

Em Django-ville, esse conceito de posts e autores poderia ser chamado de nosso


aplicativo blog. Nesse contexto, um aplicativo é um conjunto independente de modelos e
visualizações que descreve o comportamento e funcionalidade do nosso blog.
Embalados da maneira correta, muitos projetos django poderiam usar nosso aplicativo
blog. Em nosso projeto, o Blog poderia ser apenas um aplicativo. Também podemos ter
um aplicativo do Fórum, por exemplo. Mas vamos manter o escopo original do nosso
aplicativo blog.

Aqui está um preparado para este tutorial:models.py

from django.
django.db
db import models
models

class Author
Author(
(models.
models.Model
Model)):

    name = models.
models.CharField
CharField( (max_length
max_length==100
100)
)

    def __str__
__str__(
(self
self)
):

        return self
self.
.name
name

class Post
Post(
(models.
models.Model
Model)):

    title = models.
models.CharField
CharField( (max_length
max_length=
=100
100))

    content = models.
models.TextField
TextField( ()

    published_date = models.
models.DateTimeField
DateTimeField((blank
blank=
=True
True,
, null
null=
=True
True)
)

    author = models.
models.ManyToManyField
ManyToManyField( (Author
Author,, related_name
related_name=
="posts"
"posts"))

    def __str__
__str__(
(self
self)
):

        return self
self.
.title

Mais recursos python


O que é um IDE? (https://www.redhat.com/en/topics/middleware/what-is-ide?
intcmp=7016000000127cYAAQ)
Folha de trapaça: Python 3.7 para iniciantes
(https://opensource.com/downloads/cheat-sheet-python-37-beginners?
intcmp=7016000000127cYAAQ)
Principais frameworks de GUI Python (https://opensource.com/resources/python/gui-
frameworks?intcmp=7016000000127cYAAQ)
Download: 7 bibliotecas pypi essenciais (https://opensource.com/downloads/7-
essential-pypi-libraries?intcmp=7016000000127cYAAQ)
Desenvolvedores de Chapéu Vermelho (https://developers.redhat.com/?
intcmp=7016000000127cYAAQ)
Conteúdo python mais recente (https://opensource.com/tags/python?
intcmp=7016000000127cYAAQ)

Isso pode parecer um pouco assustador, então vamos acabar com isso. Temos dois
modelos: Autor e Post. Cada um tem um nome ou título. O post tem um grande campo
de texto para conteúdo e um para a data e hora de publicação. O Post também tem um ,
que une posts e autores.DateTimeFieldManyToManyField

A maioria dos tutoriais começa do zero — mas não é isso que vai acontecer na prática.
Na realidade, você vai receber um monte de código existente como o acima, e você tem
que descobrir o que tudo isso significa.model.py

Então agora é sua tarefa entrar no aplicativo e dar uma olhada ao redor. Há algumas
maneiras de fazer isso. Você pode fazer login no Django admin
(https://docs.djangoproject.com/en/1.11/ref/contrib/admin/), um backend baseado na Web
que tem todos os aplicativos listados e as maneiras de manipulá-los. Vamos voltar a
isso. aqui estamos interessados no ORM.

Podemos acessar o ORM correndo do diretório principal do nosso projeto


Django.python manage.py shell

/srv/web/django/ $ python manage.py


manage.py shell
shell

Python 3.6.3 (default


default,
, Nov  9
 9 2017
2017,
, 15
15:
:58
58:
:30
30)
)

[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.38


clang-900.0.38)
)] on darwin

darwin

Type "help"
"help",
, "copyright"
"copyright",
, "credits" or "license" for more information.

information.

(InteractiveConsole
InteractiveConsole)
)

>>>
Isso nos levará a um console interativo. O comando shell
(https://docs.djangoproject.com/en/1.11/ref/django-admin/#shell) fez muita configuração
para nós, incluindo importar nossas configurações e configurar o ambiente Django.
Embora tenhamos lançado a concha, não podemos acessar nosso modelo de Blog até
que o importemos.

>>> from blog.models import *

Isso importa todos os modelos de blog para que possamos brincar com nossos posts e
autores de blogs.

Para começar, vamos obter uma lista de todos os autores.

>>> Author.objects.all()

O que vamos obter deste comando é um de resultados, que lista todos os nossos
objetos Autor. Também não vamos encher todo o nosso console, porque se houver
muitos resultados, Django automaticamente truncará os resultados impressos.QuerySet

>>> Author.
Author.objects
objects.
.all
all(
()

<QuerySet [<Author: VM (Vicky


Vicky)
) Brasseur
Brasseur>,
>, <Author: Rikki Endsley>,
Endsley>,

 <Author: Jen Wike Huger>,


Huger>, '...(remaining elements truncated)...']
truncated)...']

Podemos selecionar um único autor usando em vez de . Mas precisamos de um pouco


mais de informação para um único disco. Em bancos de dados relacionais, as tabelas
possuem um campo-chave primário que possui um identificador único para cada registro
em uma tabela; no entanto, os nomes dos autores não são únicos. Muitas pessoas
compartilham o mesmo nome, (https://2016.katieconf.xyz/)por isso não é uma boa
restrição única. Uma maneira de contornar isso é ter uma sequência (1, 2, 3...) ou um
identificador único universal (UUID) como a chave principal. Mas como estes não são
bem utilizados pelos humanos, podemos manipular nossos objetos autor usando
.getallgetname

>>> Author.
Author.objects
objects..get
get(
(name
name=
="VM (Vicky) Brasseur")
Brasseur")

<Author: VM (Vicky
Vicky)
) Brasseur
Brasseur>>

Desta vez, temos um único objeto com o que podemos interagir, em vez de uma lista.
Podemos interagir com este objeto pythonicamente, usando qualquer uma das colunas
de tabela como atributos para olhar para o objeto.QuerySet
>>> vmb = Author.
Author.objects
objects.
.get
get(
(name
name=
="VM (Vicky) Brasseur")
Brasseur")

>>> vmb.
vmb.name
name

u'VM (Vicky) Brasseur'

And this is where the cool stuff happens. Normally in relational databases, if we want to
show information for other tables, we'd need to write a , or other table-coupling functions,
making sure that our foreign keys match up between tables. Django takes care of that for
us.LEFT JOIN

In our model, authors write many posts, so our Author object can check what posts the
author has made.

>>> vmb.
vmb.posts
posts..all
all(
()

QuerySet[
QuerySet [<Post: "7 tips for nailing your job interview">,
interview">,

 <Post: "5 tips for getting the biggest bang for your cover letter buck">,
buck">,

 <Post: "Quit making these 10 common resume mistakes">,


mistakes">,

 '...(remaining elements truncated)...']


truncated)...']

We can manipulate using normal pythonic list manipulations.QuerySets

>>> for post in vmb.


vmb.posts
posts.
.all
all(
():

...   print
print(
(post.
post.title
title)
)

...

...

7 tips for nailing your job interview

interview

5 tips for getting the biggest bang for your cover letter buck

buck

Quit making these 10 common resume mistakes

To do more complex querying, we can use filters instead of getting everything. Here is
where it gets tricky. In SQL, you have options such as , , and other filtering objects. You
can do all these things in the ORM, too, but it has a special way of doing them: by using
implicitly (rather than explicitly) defined functions.likecontains

If I call a function in my Python script, I'd expect somewhere there would be a matching .
This is an explicit functional definition. However, in the ORM, you can call a function that
isn't explicitly defined. Before, we were using to match on a name. But, if we wanted to do
a substring search, we can use .do_thing()def do_thingnamename__contains

>>> Author.
Author.objects
objects.
.filter
filter(
(name__contains
name__contains=
="Vic"
"Vic")
)

QuerySet[
QuerySet[<Author: VM (Vicky
Vicky)
) Brasseur
Brasseur>,
>, <Author: Victor Hugo">]
Hugo">]

Now, a small note about the double underscore (). These are very Python. You may have
seen or in your travels in Pythonland. These are sometimes referred to as , a shortening
of "double underscore." There are only a few non-alphanumeric characters that can be
used in object names in Python; underscore is one of them. These are used in the ORM
as an explicit separator of different parts of the filter key name. Under the hood, the string
is split by these underscores, and the tokens are processed separately. gets changed into
. In other programming languages, you may use arrows instead, such as in PHP. Don't let
dunders scare you, they're just pythonic helpers! (And if you squint, you could say they
look like little snakes, little pythons that want to help you with your
code.)____main____repr__dunder methodsname__containsattribute: name, filter: containsname->contain

The ORM is extremely powerful and very pythonic. But what about that Django admin site
I mentioned above?

One of the brilliant user-accessibility features of Django is its admin interface. If you
define your models, you get a nice web-based editing portal, for free.

And what powers this? The ORM.


That's right! Given the code used to create the original models, Django turned that into a
web-based portal, which is powered using the same raw functions we used earlier. By
default, the admin is basic, but it's just a matter of adding more definitions in your model
to change how the admin looks. For example, those methods from earlier? We use those
to define what an Author object looks like (in this case, just the name of the author). With
a bit of work, you can make an interface that feels like a full content management system
that allows your users to edit their own content with ease (for example, adding fields and
filters for marking a post "published").__str__

If you'd like to know more, the Django Girls tutorial (https://djangogirls.org) section
about the ORM (https://tutorial.djangogirls.org/en/django_orm/) has a detailed
walkthrough. There's also copious documentation on the Django project website
(https://docs.djangoproject.com/en/1.11/topics/db/).

Topics :
Python (/tags/python) Web development (/tags/web-development)

About the author


Katie McLaughlin - Katie has worn many different hats over the years. She has
previously been a software developer for many languages, systems administrator for
multiple operating systems, and speaker on many different topics.
When she's not
changing the world, she enjoys making cooking, tapestries, and seeing just how well
(/users/glasnt) various application stacks handle emoji.

• More about me (/users/glasnt)

Você também pode gostar