Aula 12 – Curso de Django

Criando uma primeira aplicação com Django e mysql

Interagindo com a API de banco de dados da nossa aplicação web polls na prática

https://docs.djangoproject.com/pt-br/1.11/intro/tutorial02/

Interagindo com a API de banco de dados

Interagindo com a API de banco de dados

Brincando com a API

Agora vamos dar uma olhada no shell interativo do Python e brincar um pouco com a API do Django.

Para invocar o shell do Python, use esse comando:

python manage.py shell

Nós usaremos isso em vez de simplesmente digitar “python”, porque o manage.py configura a variável de ambiente DJANGO_SETTINGS_MODULE, que da ao Django o caminho de importação Python, do arquivo mysite/settings.py.

Ignorando manage.py

Se você optar por não usar o manage.py, não há problemas. Apenas configure a variável de ambiente DJANGO_SETTINGS_MODULE para mysite.settings, inicie um shell Python puro e configure o Django:

import django
django.setup()

Se levantar um AttributeError, você provavelmente está usando uma versão do Django que não funciona com está versão do tutorial. Então será preciso mudar para um tutorial mais velho ou mudar para a versão mais recente do Django.

Você deve rodar python a partir do mesmo diretório que manage.py está, ou garantir que este diretório esteja no caminho do Python, e assim import mysite funcionará.

Assim que você estiver no shell, explore a API de banco de dados:

# Importa as classes modelo que escrevemos (Question e Choice).
from polls.models import Question, Choice


# Nenhuma questão está no Sistema ainda
Question.objects.all()


# Cria uma nova questão.
# Suporte para time zones está habilitado por padrão no settings, então
#  o Django espera uma datetime com tzinfo para pub_date. Use timezone.now()
# ao invés de datetime.datetime.now() e ele fará tudo correto.
from django.utils import timezone
q = Question(question_text="O que há de novo?", pub_date=timezone.now())


# Salva o objeto no banco de dados. Você deve chamar save () explicitamente.
q.save()
# Agora a questão criada tem um ID. Observe que dependendo de qual banco de dados #você está usando, ele pode retornar "1L" em vez de "1".
#Isso significa que o backend de seu banco de dados prefere retornar inteiros como tipo #long do Python.
q.id
1


# Acesse os valores do campo do modelo através dos atributos do Python.
q.question_text
"O que há de novo? "
q.pub_date
datetime.datetime(2017, 9, 18, 23, 55, 34, 427312, tzinfo=<UTC>)


#Altere os valores alterando os atributos, depois chame o save ().
>>> q.question_text = "E aí, novidades?"
>>> q.save()

# objects.all() exibe todas as Questions no banco de dados.
Question.objects.all()
<QuerySet [<Question: Question object>]>

Note que <Question: Question object> é uma representação totalmente inútil. Vamos corrigir isso editando o model da Question (no arquivo polls/models.py), adicionando um método __str__() a ambos modelos: Question e Choice.

No arquivo polls/models.py inserir o código:


from django.db import models
from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible # somente se você precisar de suporte ao Python 2
class Question(models.Model):
    # ...
    def __str__(self):
        return self.question_text
@python_2_unicode_compatible # somente se você precisar de suporte ao Python 2
class Choice(models.Model):
    # ...
    def __str__(self):
        return self.choice_text

É importante adicionar métodos __str__() aos seus models, não apenas para sua própria conveniência quando estiver lidando com o prompt interativo, mas também porque representações de objetos são usadas por todo projeto gerado automaticamente pelo Django.

Note que esses são métodos Python normais. Vamos adicionar um método personalizado, apenas para demonstração:


import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

Note que a adição do import datetime e from django.utils import timezone é para referenciar o módulo padrão do Python datetime e o modulo Django utilitário de fuso horário django.utils.timezone, respectivamente.

Salve essas mudanças e vamos iniciar uma nova sessão do shell interativo do Python rodando novamente:

python manage.py shell

Já no shell digite:

# Importa as classes dos modelos que escrevemos.
>>> from polls.models import Question, Choice
# Certifique-se de que o nosso __str __ () tenha funcionado.
Question.objects.all()
[<Question: E aí, novidades?>]>

# O Django fornece uma API de pesquisa de banco de dados rica, que é inteiramente #orientada por argumentos de palavras->>>chave
>>>Question.objects.filter(id=1)
QuerySet [<Question: E aí, novidades?>]
>>>Question.objects.filter(question_text__startswith='E')
[<Question: E aí, novidade?>]>
# Obtem as perguntas que foram publicadas este ano
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: E aí, novidades?>
#Solicitação de um ID que não existe, isso levantará uma exceção.

>>>Question.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Question matching query does not exist.


# A pesquisa por uma chave primária é o caso mais comum, então o Django fornece um
# atalho para pesquisas exatas de chave primária.
#Isso é idêntico a Question.objects.get (id = 1).
>>> Question.objects.get(pk=1)

# Certifique-se de que nosso método personalizado funcionou.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True


# Dê a questão algumas escolhas. A chamada create cria um novo
# objeto Choice, a instrução INSERT, adiciona a Choice ao conjunto
# das Choices disponíveis e retorna o novo objeto Choice. Django cria
# um conjunto para manter o "outro lado" de uma relação de Chave Estrangeira
>>> q = Question.objects.get(pk=1)

# Exibir qualquer Choice do conjunto de objetos relacionados - nenhum até agora.
>>> q.choice_set.all()
# Cria três choices (escolhas).
>>> q.choice_set.create(choice_text='Não Muito', votes=0)
>>> q.choice_set.create(choice_text='O céu', votes=0)
>>> c = q.choice_set.create(choice_text='Apenas hackeando novamente', votes=0)
>>> c

# Os objetos Choice têm acesso à API para seus objetos de Question relacionados.
>>> c.question

# And vice versa: Os objetos Question obtêm acesso aos objetos Choice.
>>> q.choice_set.all()
<QuerySet [<Choice: Não muito>, <Choice: O céu>, <Choice: Apenas hackeando novamente >]>

>>> q.choice_set.count()
3


# A API segue automaticamente os relacionamentos tanto quanto você precisar.
# Use sublinhados duplos para separar relacionamentos.
# Isso funciona com tantos níveis quanto você quiser; não há limite.
# Encontre todas as Choice para qualquer Question cujo pub_date esteja neste ano
# (reutilizando a variável 'current_year' que criamos acima).
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Não muito >, <Choice: O céu >, <Choice: Apenas hackeando novamente >]>


# Vamos excluir uma das Choices. Use delete () para isso.
>>> c = q.choice_set.filter(choice_text__startswith='Apenas hackeando')
>>> c.delete()

Para baixar o código como está até agora, acesse o meu github no link abaixo:
https://github.com/toticavalcanti/django_course/tree/add_str_method_to_models

AULA  11

AULA  13

Todas as Aulas da App Polls

Página Principal

Obrigado

Até a próxima

Aula 12 – Interagindo com a API de banco de dados na prática

About The Author
-

4 Comentários

  • Ricardo
    Reply

    Fala Toti!
    Cara, tô avançando!
    Mas quando do um python manage.py shell
    Da o erro abaixo.
    Eu não consegui encontrar uma solução
    preciso adicionar, mas fiquei na dúvida se é no mysite ou dentro do django
    import django
    django.setup()

    Obrigado por enquanto!

    Traceback (most recent call last):
    File “manage.py”, line 5, in
    django.setup()
    File “C:\Users\rlpro\appData\Local\Programs\Python\Python37\lib\site-packages\django\__init__.py”, line 19, in setup
    configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
    File “C:\Users\rlpro\appData\Local\Programs\Python\Python37\lib\site-packages\django\conf\__init__.py”, line 56, in __getattr__
    self._setup(name)
    File “C:\Users\rlpro\appData\Local\Programs\Python\Python37\lib\site-packages\django\conf\__init__.py”, line 41, in _setup
    % (desc, ENVIRONMENT_VARIABLE))
    django.core.exceptions.ImproperlyConfigured: Requested setting LOGGING_CONFIG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

    • toticavalcanti
      Reply

      O erro diz:
      django.core.exceptions.ImproperlyConfigured: Requested setting LOGGING_CONFIG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

      Ou seja, a variável de ambiente DJANGO_SETTINGS_MODULE não tá definida.

      Dá uma olhada no seu manage.py, vê se ele tá assim:

      #!/usr/bin/env python3
      import os
      import sys

      if __name__ == “__main__”:
      os.environ.setdefault(“DJANGO_SETTINGS_MODULE”, “mysite.settings”)
      try:
      from django.core.management import execute_from_command_line
      except ImportError as exc:
      raise ImportError(
      “Couldn’t import Django. Are you sure it’s installed and ”
      “available on your PYTHONPATH environment variable? Did you ”
      “forget to activate a virtual environment?”
      ) from exc
      execute_from_command_line(sys.argv)

      É nele que a variável de ambiente DJANGO_SETTINGS_MODULE é definida.

      Cuidado com a identação, tem que tá certinha.

      Pra rodar esse comando:
      python manage.py shell

      Tem que entrar na pasta onde o manage.py está.

      Tenta aí.

      Qualquer coisa me fala.

      Abs,
      Toti

  • Romulo
    Reply

    E ai man, blz eu perturbando de novo rs. ao executar o segundo comando do python shell vem o erro abaixo se poder ajudar
    res = self._query(query)
    File “/home/romulo/django_codes/AmbientePython3/lib/python3.6/site-packages/MySQLdb/cursors.py”, line 412, in _query
    rowcount = self._do_query(q)
    File “/home/romulo/django_codes/AmbientePython3/lib/python3.6/site-packages/MySQLdb/cursors.py”, line 375, in _do_query
    db.query(q)
    File “/home/romulo/django_codes/AmbientePython3/lib/python3.6/site-packages/MySQLdb/connections.py”, line 276, in query
    _mysql.connection.query(self, query)
    django.db.utils.OperationalError: (1054, “Unknown column ‘polls_question.question_text’ in ‘field list'”)

    • toticavalcanti
      Reply

      Fala Romulo, blz? Pode pertubar, a ideia é essa mesmo.
      Cara, pelo que estou lendo no erro, o problema tá em no campo question_text do model polls, o erro diz:
      django.db.utils.OperationalError: (1054, “Unknown column ‘polls_question.question_text’ in ‘field list’”)
      Ele diz que desconhece a coluna question_text de polls_question, provavelmente alguma coisa deu errada no seu banco de dados na hora de criar o banco ou na hora da migração.
      Faz o seguinte, entra no console do mysql, roda um drop database no banco que você criou, depois recria ele novamente, roda o migrate e tenta de novo.
      Vlw, qualquer coisa dá um toque. \O/

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>