134

Djangogirls Tutorial Pt

Embed Size (px)

DESCRIPTION

apostila de django

Citation preview

Page 1: Djangogirls Tutorial Pt
Page 2: Djangogirls Tutorial Pt

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

TabeladeconteúdosIntrodução

Comofuncionaainternet?

Introduçãoàlinhadecomando

InstalaçãodoPython

EditordeCódigo

IntroduçãoaoPython

OqueéDjango?

InstalaçãodoDjango

Criandoumprojeto

ModelosdoDjango

Administração

Implantação!

Urls

Views-horadecriar!

IntroduçãoaHTML

DjangoORM(Querysets)

Dadosdinâmicosnostemplates

Templates

CSS-Deixemaisbonito

Estendendoostemplates

Ampliesuaaplicação

Formulários

Domínio

Oquevemdepois?

DjangoGirlsTutorial

2

Page 3: Djangogirls Tutorial Pt

TutorialDjangoGirls

EstetrabalhoélicenciadosobalicençaCreativeCommonsAttribution-ShareAlike4.0.Paraverumacópiadestalicença,visitehttp://creativecommons.org/licenses/by-sa/4.0/

TranslationThistutorialhasbeentranslatedfromEnglishtoPortuguesebyagroupofawesomevolunteers.SpecialthanksforhelpgoesouttoWillieLawrence,VivianMacedo,CleitonLima,danieltex,LeandroSilvaAraujo,AdailtondoNascimento,PabloPalacios,PauloAlem,EricHideki,JoaoLuizLorencetti,clemente.jnr,LeonardoAlvesdosSantos,joepreludian,GabrielaCavalcantedaSilve,RafaelBiagionideFazio,FabioC.BarrionuevodaLuz,ffabiorj,LucasMagnum,1pedro,AdjamiltonJunior,LeandroBarbosa,KleberCPinheiro,KatyannaMoura,AnnandaSousa,FlavioBarros,MarcelRibeiroDantas,AdamVictorNazarethBrandizzi,BernardoFontes,AntonioLuis,RaonyGuimaresCorreodoCarmoLisboaCardenas,CamillaAchuttiandCarlaSuarez.Wow!<3<3

IntroduçãoVocêjásentiucomoseomundofossecadavezmaissobretecnologiaequedealgumaformavocêtenhaficadopratrás?Vocêjáimaginoucomoseriacriarumwebsitemasnuncatevemotivaçãosuficienteparacomeçar?Vocêjápensouqueomundodosoftwareécomplicadodemaisatéparatentarfazeralgumacoisasozinho?

Bem,nóstemosboasnotíciasparavocê!Programaçãonãoétãodifícilquantopareceenósqueremostemostraroquãodivertidopodeser.

Estetutorialnãoirátetransformarmagicamenteemumprogramador.Sevocêquerserbomnissoprecisademesesouatémesmoanosdetreinoeprática.Masnósqueremostemostrarqueaprogramaçãooucriaçãodewebsitesnãoétãocomplicadaquantoparece.Nóstentaremosexplicarosdiferentespedaçostãobemquantopudermos,talquevocênãosesintaintimidadopelatecnologia.

Nósesperamosconseguirfazervocêamaratecnologiatantoquantonósamamos!

Oquevocêiráaprenderduranteotutorial?

DjangoGirlsTutorial

3Introdução

Page 4: Djangogirls Tutorial Pt

Quandovocêtiverterminadootutorialvocêteráumaaplicaçãowebsimplesefuncional:seupróprioblog.Nósvamosmostrarcomocolocá-loonline,paraqueoutrosvejamseutrabalho!

Eleseparecerá(maisoumenos)comisso:

Sevocêseguirotutorialporcontaprópriaenãotiverumtreinadorparaajudaremcasodequalquerproblema,nóstemosumchatparavocê: 1.Nóspedimosaosnossostreinadoreseparticipantesanterioresparaacessaremládetemposemtemposeajudaremoutroscomotutorial!Nãotenhamedodefazersuaperguntalá!

OK,vamospelocomeço...

SobreotutorialecontribuiçõesEstetutorialémantidoporDjangoGirls.Sevocêencontrarquaisquererrosouquiseratualizarotutorial,porfavorsigaasorientaçõesdecontribuição.

DjangoGirlsTutorial

4Introdução

Page 5: Djangogirls Tutorial Pt

Gostariadenosajudaratraduzirotutorialparaoutrosidiomas?nomomento,astraduçõesestãosendomantidasnaplataformacrowdin.comem:

https://crowdin.com/project/django-girls-tutorial

Seoseuidiomanãoestálistadonocrowdin,porfavoropenanewissueinformandooidiomaparaquepossamosadicioná-lo.

DjangoGirlsTutorial

5Introdução

Page 6: Djangogirls Tutorial Pt

ComofuncionaainternetEstecapítuloéinspiradonapalestra"ComoaInternetfunciona"deJessicaMcKellar(http://web.mit.edu/jesstess/www/).

ApostamosquevocêusaaInternettodososdias.Masvocêsaberealmenteoqueacontecequandovocêdigitaumendereçocomohttp://djangogirls.orgemseunavegadorepressiona'Enter'?

Aprimeiracoisaquevocêprecisaentenderéqueumsiteésóummontedearquivossalvosemumdiscorígido.Assimcomoseusfilmes,músicasoufotos.Noentanto,háumapartequeéexclusivaparasites:essaparteincluicódigosdecomputadorchamadoHTML.

Sevocênãoestiverfamiliarizadacomaprogramação,podeserdifícilcompreenderoHTMLnocomeço,masseusnavegadoresdaweb(comooChrome,Safari,Firefox,etc)amamele.NavegadoresdaWebsãoprojetadosparaentenderessecódigo,seguirsuasinstruçõeseapresentartodosessesarquivosdequeseusiteéfeitoexatamentedojeitoquevocêquerqueelessejamapresentados.

Igualàtodososarquivos,osarquivosHTMLprecisamserarmazenadosnumdiscorígido.Prainternetnósusamospoderososcomputadoresespeciaischamadosservidores.Elesnãotêmumatela,omouseouoteclado,porquesuafinalidadeprincipaléparaarmazenardadoseservi-los.Éporissoqueelessãochamadosdeservidores..--porqueelesservemavocê,dados.

OK,masvocêquersabercomoquêainternetseparece,certo?

Fizemosumdesenhopravocê!Veja:

DjangoGirlsTutorial

6Comofuncionaainternet?

Page 7: Djangogirls Tutorial Pt

Quebagunçané?Naverdadeéumarededemáquinasconectadas(osservidoresmencionadosacima).Centenasdemilharesdemáquinas!Muitos,muitosquilômetrosdecabosemtodoomundo!Paraverquãocomplicadaainternetévocêpodevisitarumsite(http://submarinecablemap.com/)quemostraummapacomoscabossubmarinos.Aquiestáumscreenshotdosite:

DjangoGirlsTutorial

7Comofuncionaainternet?

Page 8: Djangogirls Tutorial Pt

Fascinante,não?Mas,obviamente,nãoépossívelterumfioconectadoatodamáquinaligadanainternet.Logo,parachegaremumamáquina(porexemploaquelaondehttp://djangogirls.orgestásalva)nósprecisamospassarumarequisiçãopormuitasmáquinasdiferentes.

Separececomisso:

Imaginequequandovocêdigitahttp://djangogirls.orgvocêenviaumacartaquediz:"QueridoDjangoGirls,eudesejoverositedjangogirls.org.Envieelepramim,porfavor!"

Suacartavaiparaaagênciadoscorreiosmaispróximadevocê.Depoisvaiparaoutraqueéumpoucomaispertodoseudestinatário,depoisparaoutraeoutraatéquesejaentregueaoseudestino.Oúnicodiferencialéquesevocêenviarcartas(pacotesdedados)comfreqüênciaparaomesmolugar,cadacartapodepassarpordiferentesagênciasdecorreios(roteadores),dependendodecomoelassãodistribuídasemcadaagência.

DjangoGirlsTutorial

8Comofuncionaainternet?

Page 9: Djangogirls Tutorial Pt

Sim,ésimplesassim.Vocêenviamensagenseesperaalgumaresposta.Claro,aoinvésdepapelecanetavocêusabytesdedados,masaideiaéamesma!

Aoinvésdeendereçoscomonomedarua,cidade,códigopostalenomedopaís,nósusamosendereçosIP.PrimeiroseucomputadorperguntapeloDNS(DomainNameSystem-SistemadeNomedeDomínio)paratraduzirdjangogirls.orgparaumendereçoIP.Ofuncionamentodelesepareceumpoucocomasantigaslistastelefônicasondevocêpodeolharparaonomedapessoaquequerentraremcontatoeacharoseunúmerodetelefoneeendereço.

Quandovocêenviaumacarta,elaprecisatercertascaracterísticasparaserentreguecorretamente:umendereço,selo,etc.Vocêtambémusaumalinguagemqueoreceptadorcompreende,certo?Omesmoacontececompacotesdedadosquevocêenviaparaverumsite:vocêusaumprotocolochamadoHTTP(HypertextTransferProtocol-ProtocolodeTransferênciadeHipertexto).

Então,basicamente,quandovocêtemumsitevocêprecisaterumservidor(máquina)ondeeleficahospedado.Oservidorestáàesperadequaisquerrequisiçõesrecebidas(cartasquesolicitamaoservidoroenviodoseusite)eeleenviadevoltaseusite(emoutracarta).

ComoesteéumtutorialdeDjangovocêvaiperguntaroqueoDjangofaz.Quandoenviaumarespostanemsemprevocêquerenviaramesmacoisaparatodomundo.Émuitomelhorsesuascartassãopersonalizadas,especialmenteparaapessoaqueacaboude

DjangoGirlsTutorial

9Comofuncionaainternet?

Page 10: Djangogirls Tutorial Pt

escreverparavocê,certo?ODjangoajudavocêacriaressaspersonalizadaseinteressantescartas:).

Chegadefalar,éhoradecriar!

DjangoGirlsTutorial

10Comofuncionaainternet?

Page 11: Djangogirls Tutorial Pt

IntroduçãoàlinhadecomandoÉemocionante,não?!Vocêvaiescreversuaprimeiralinhadecódigoempoucosminutos:)

Deixe-nosapresentá-loaoseuprimeironovoamigo:alinhadecomando!

Asetapasaseguirmostrarãoavocêcomousarajanelapretaquetodososhackersusam.Podeparecerumpoucoassustadornocomeço,masrealmenteéapenasumpromptesperandoporcomandosdevocê.

Qualéalinhadecomando?Ajanela,quenormalmenteéchamadadelinhadecomandoouinterfacedelinhadecomando,éumaplicativobaseadoemtextoparavisualização,manipulaçãoemanuseiodearquivosemseucomputador(comoporexemplo,oWindowsExplorerouoFindernoMac,masseminterfacegráfica).Outrosnomesparaalinhadecomandosão:cmd,CLI,prompt,consoleouterminal.

AbraainterfacedelinhadecomandoParacomeçaralgunsexperimentos,precisamosabriranossainterfacedelinhadecomandoprimeiro.

Windows

VáemIniciar→TodososProgramas→Acessórios→Promptdecomando.

MacOSX

Applications→Utilities→Terminal.

Linux

ProvavelmentevocêvaiacharemApplications→Accessories→Terminal,masissodependedoseusistemaoperacional.QualquercoisaésóprocurarnoGoogle:)

Prompt

DjangoGirlsTutorial

11Introduçãoàlinhadecomando

Page 12: Djangogirls Tutorial Pt

Agoravocêdeveverumajanelabrancaoupretaqueestáàesperadeseuscomandos.

SevocêestiveremMacounumLinux,vocêprovavelmenteveráum``$,comoeste:

$

NoWindows,éumsinalde>,comoeste:

>

Cadacomandoseráantecedidoporestesinaleumespaço,masvocênãoprecisadigitá-lo.Seucomputadorfaráissoporvocê:)

Apenasumapequenanota:noseucaso,talvezháalgocomoC:\Users\ola>ouOlas-MacBookAir:~ola$antesdosinaldopromptistoestará100%correto.Nestetutorialnósapenassimplificaremoseleparaomínimo.

Seuprimeirocomando(YAY!)Vamoscomeçarcomalgosimples.Digiteoseguintecomando:

$whoami

ou

>whoami

DepoisteclaEnter.Essaénossasaída:

$whoami

olasitarska

Comovocêpodever,ocomputadorsóapresentouseunomedeusuário.Elegante,né?:)

Tentedigitarcadacomando,nãocopiarecolar.Vocêvaiselembrarmaisdessaforma!

OBásico

DjangoGirlsTutorial

12Introduçãoàlinhadecomando

Page 13: Djangogirls Tutorial Pt

Cadasistemaoperacionaltemoseupróprioconjuntodeinstruçõesparaalinhadecomando,entãosecertifiquequevocêestáseguindoasinstruçõesdoseusistemaoperacional.Vamostentar,certo?

Pastaatual

Serialegalsaberemquepastaestamosagora,certo?Vamosver.Digiteoseguintecomandoseguidodeumenter:

$pwd

/Users/olasitarska

SevocêestivernoWindows:

>cd

C:\Users\olasitarska

Provavelmentevocêvaiveralgoparecidonasuamáquina.UmvezquevocêabrealinhadecomandovocêjácomeçanapastaHome.

Nota:'pwd'significa'printworkingdirectory'.

Listandoarquivosepastas

Entãooquetemnele?Serialegaldescobrir.Vamosver:

$ls

Applications

Desktop

Downloads

Music

...

Windows:

>dir

DirectoryofC:\Users\olasitarska

05/08/201407:28PM<DIR>Applications

05/08/201407:28PM<DIR>Desktop

05/08/201407:28PM<DIR>Downloads

05/08/201407:28PM<DIR>Music

...

DjangoGirlsTutorial

13Introduçãoàlinhadecomando

Page 14: Djangogirls Tutorial Pt

Entraremoutrapasta

TalvezagentequeiraentrarnanossapastaDesktop?

$cdDesktop

Windows:

>cdDesktop

Vejaserealmenteentramosnapasta:

$pwd

/Users/olasitarska/Desktop

Windows:

>cd

C:\Users\olasitarska\Desktop

Aquiestá!

Dicadeprofissional:sevocêdigitarcdDeapertarateclatabnoseuteclado,alinhadecomandoirápreencherautomaticamenteorestodonomeparaquevocêpossanavegarrapidamente.Sehouvermaisdeumapastaquecomececom"D",aperteateclatabduasvezesparaobterumalistadeopções.

Criandoumapasta

QuetalcriarumdiretórioDjangoGirlsnasuaáreadetrabalho?Vocêpodefazerassim:

$mkdirdjangogirls

Windows:

>mkdirdjangogirls

DjangoGirlsTutorial

14Introduçãoàlinhadecomando

Page 15: Djangogirls Tutorial Pt

Estecomandovaicriarumapastacomonomedjangogirlsnonossodesktop.Vocêpodeverificarseeleestálá,sódeolharnasuaáreadetrabalhoouexecutandoumcomandols/dir!Experimente:)

Dicadeprofissional:Sevocênãoquiserdigitaromesmocomandováriasvezes,tentepressionarsetaparacimaesetaparabaixonotecladoparapercorrercomandosusadosrecentemente.

Exercite-se!

Umpequenodesafioparavocê:nasuamaisnovapastacriadadjangogirlscrieumaoutrapastachamadateste.Useoscomandoscdemkdir.

Solução:

$cddjangogirls

$mkdirteste

$ls

teste

Windows:

>cddjangogirls

>mkdirteste

>dir

05/08/201407:28PM<DIR>teste

Parabéns!:)

Limpando

Nãoqueremosdeixarumabagunça,entãovamosremovertudooquefizemosatéagora.

PrimeiroprecisamosvoltarparaapastaDesktop:

$cd..

Windows:

DjangoGirlsTutorial

15Introduçãoàlinhadecomando

Page 16: Djangogirls Tutorial Pt

>cd..

Fazendocdpara..nósmudaremosdodiretórioatualparaodiretóriopai(quesignificaodiretórioquecontémodiretórioatual).

Vejaondevocêestá:

$pwd

/Users/olasitarska/Desktop

Windows:

>cd

C:\Users\olasitarska\Desktop

Agoraéhoradeexcluirodiretóriodjangogirls.

Atenção:Aexclusãodearquivosusandodel,rmdirourméirrecuperável,significandoArquivosexcluídosvãoemboraparasempre!Então,tenhacuidadocomestecomando.

$rm-rdjangogirls

Windows:

>rmdir/Sdjangogirls

djangogirls,Temcerteza<S/N>?S

Pronto!Paratercertezaqueapastafoiexcluída,vamoschecar:

$ls

Windows:

>dir

Saindo

Porenquantoéisso!Agoravocêfecharalinhadecomandocomsegurança.Vamosfazerdojeitohacker,certo?:)

DjangoGirlsTutorial

16Introduçãoàlinhadecomando

Page 17: Djangogirls Tutorial Pt

$exit

Windows:

>exit

Legal,né?:)

SumárioAquivaiumalistadealgunscomandosúteis:

Comando(Windows)

Comando(MacOS/Linux) Descrição Exemplo

exit exit Fechaajanela exit

cd cd Mudaapasta cdtest

dir ls Listaaspastaseosarquivos dir

copy cp Copiaumarquivo copyc:\test\test.txtc:\windows\test.txt

move mv Moveumarquivo movec:\test\test.txtc:\windows\test.txt

mkdir mkdir Criaumapasta mkdirtestdirectory

del rm Deletaumapastae/ouarquivo delc:\test\test.txt

Estessãoapenasalgunsdospoucoscomandosquevocêpodeexecutaremsualinhadecomando,masvocênãovaiusarmaisnadadoqueistohoje.

Sevocêestivercurioso,ss64.comcontémumareferênciacompletadecomandosparatodosossistemasoperacionais.

Pronto?VamosmergulharnoPython!

DjangoGirlsTutorial

17Introduçãoàlinhadecomando

Page 18: Djangogirls Tutorial Pt

VamoscomeçarcomPythonFinalmentechegamosaqui!

Masprimeiro,vamosfalarumpoucosobreoqueoPythoné.Pythonéumalinguagemdeprogramaçãomuitopopularquepodeserusadaparacriarsites,jogos,softwarescientíficos,gráficosemuito,muitomais.

OPythonéorigináriodadécadade1980eseuprincipalobjetivoéserlegívelporsereshumanos(nãoapenasmáquinas!),porissoeleparecemuitomaissimplesdoqueoutraslinguagensdeprogramação.Issofazelemaisfácildeaprender,masnãoseengane,Pythontambémémuitopoderoso!

InstalaçãodoPythonEstesubcapítuloébaseadoemumtutorialcriadoporGeekGirlsCarrots(http://django.carrots.pl/)

DjangoéescritoemPython.NóprecisamosdeleparafazerqualquercoisaemDjango.Vamoscomeçarcomsuainstalação!NósqueremosquevocêinstaleoPython3.4,entãosevocêtemqualquerversãoanterior,vocêvaiprecisaratualizá-la.

Windows

VocêpodebaixaroPythonparaWindowsnowebsitehttps://www.python.org/downloads/release/python-343/.Depoisdefazerodownloaddoarquivo*.msi,vocêprecisaexecutá-lo(dandoumduplo-cliquenele)eseguirasinstruções.Éimportantelembrarocaminho(apasta)ondevocêinstalouoPython.Elaseráútildepois!

Cuidadocomumacoisa:nasegundateladoassistentedeinstalação,marcado"Customize",certifique-sevocêrolarparabaixoeescolhaaopção"Adicionarpython.exeparaocaminho",comoem

DjangoGirlsTutorial

18InstalaçãodoPython

Page 19: Djangogirls Tutorial Pt

Linux

ÉmuitoprovávelquevocêjátenhaoPythoninstaladoeconfigurado.Paratercertezaseeleestáinstalado(equalasuaversão),abraumterminaledigiteoseguintecomando:

$python3--version

Python3.4.2

SevocênãotemoPythoninstaladoouquerumaversãodiferente,vocêpodeinstalá-lodaseguintemaneira:

Ubuntu

Digiteoseguintecomandonoterminal:

sudoapt-getinstallpython3.4

Fedora

Useoseguintecomandonoterminal:

DjangoGirlsTutorial

19InstalaçãodoPython

Page 20: Djangogirls Tutorial Pt

sudoyuminstallpython3.4

OSX

Vocêprecisaacessarositehttps://www.python.org/downloads/release/python-342/ebaixaroinstaladordoPython:

downloaddoinstaladorMacOSX64-bit/32-bitDMG,Dêumduplo-cliqueparaabri-lo,Dêumduplo-cliquenoPython.mpkgparaexecutaroinstalador.

VerifiqueseainstalaçãofoibemsucedidaabrindooTerminaledigitandoocomandopython3:

$python3--version

Python3.4.2

Sevocêtiverqualquerdúvidaousealgumacoisadeuerradoevocênãosabeoquefazer-porfavorpergunteaoseuinstrutor!Àsvezes,ascoisasnãoestãoindobemeémelhorpedirajudaaalguémcommaisexperiência.

DjangoGirlsTutorial

20InstalaçãodoPython

Page 21: Djangogirls Tutorial Pt

EditordeCódigoVocêestáprestesaescreversuaprimeiralinhadecódigo,entãoéhoradebaixarumeditordecódigo!

Existemmuitoseditoresdiferenteseemgrandeparteseresumeapreferênciapessoal.AmaioriadosprogramadoresPythonusaascomplexas,masextremamentepoderosasIDEs(IntegratedDevelopmentEnvironments,ouemportuguês,AmbientededesenvolvimentoIntegrado),taiscomoPyCharm.Parauminiciante,entretanto,estasIDE'ssãomenosconvenientes;nossasrecomendaçõessãobemmaissimples,porém,igualmentepoderosas.

Nossassugestõesestãoabaixo,massinta-selivreparaperguntaraoseucoachquaissãoassuaspreferências-assimvaisermaisfácilobteraajudadeles.

GeditGeditéumeditoropen-source,gratuito,disponívelparatodosossistemasoperacionais.

Baixeaqui

SublimeText2SublimeText2éumeditormuitopopularcomumperíododeavaliaçãogratuita.Éfácildeinstalareusar,eestádisponívelparatodosossistemasoperacionais.

Baixeaqui

AtomAtoméumnovoeditordecódigocriadopeloGitHub.Eleégratuito,open-source,fácildeinstalarefácildeusar.EstádisponívelparaWindows,OSXeLinux.

Baixeaqui

Porqueestamosinstalandoumeditordecódigo?

DjangoGirlsTutorial

21EditordeCódigo

Page 22: Djangogirls Tutorial Pt

VocêdeveestarseperguntandoporqueestamosinstalandoessesoftwareeditordecódigoespecialaoinvésdeusaralgocomoWordouBlocodeNotas.

Primeiroéquecódigoprecisasertextosemformatação,eoproblemacomprogramascomoWordeTexteditéqueelesnaverdadenãoproduzemtextosemformatação,elesfazem"richtext"(comfonteseformatação),usandoformatospersonalizadoscomoRTF.

Asegundarazãoéqueeditoresdecódigosãoespecializadosemeditarcódigo,entãoelespodemoferecerrecursosúteis,comorealcedecódigocomcoresdeacordocomoseusignificado,ouautomaticamentefecharcitaçõesparavocê.

Nósvamosverissoemaçãodepois.Embrevevocêteráseueditordecódigocomoumadassuasferramentasfavoritas.:)

DjangoGirlsTutorial

22EditordeCódigo

Page 23: Djangogirls Tutorial Pt

IntroduçãoaoPythonPartedestecapítuloébaseadonosTutoriaisdeGeekGirlsCarrots(http://django.carrots.pl/).

Vamosescreverumpoucodecódigo!

InterpretadorPythonParacomeçarabrincarcomPythonnósprecisamosabrirumalinhadecomandonoseucomputador.Vocêjásabedevercomofazerisso--vocêaprendeuissonocapítuloIntroduçãoàLinhadeComando.</p>Assimqueestiverpronto,sigaasinstruçõesabaixo.

NósqueremosabriroPythonnumterminal,entãodigitepython3etecleEnter.

$python3

Python3.4.2(...)

Type"copyright","credits"or"license"formoreinformation.

>>>

SeuprimeirocomandoPython!DepoisdeexecutarocomandoPython,opromptmudoupara>>>.Paranós,issosignificaqueporenquantosóutilizaremoscomandosnalinguagemPython.Vocênãoprecisadigitar>>>-OPythonfaráissoporvocê.

SevocêdesejasairdoconsoledoPython,apenasdigiteexit()ouuseoatalhoCtrl+ZnoWindowseCtrl+DnoMac/Linux.Entãovocênãovaivermaiso>>>.

MasagoranãoqueremossairdalinhadecomandodoPython.Queremosaprendermaissobreele.Vamos,então,fazeralgomuitosimples.Porexemplo,tentedigitaralgumaoperaçãomatemática,como2+3eaperteEnter.

>>>2+3

5

Incrível!Vêcomoarespostasimplesmenteaparece?OPythonconhecematemática!Vocêpodetentaroutroscomandoscomo:-4*5-5-1-40/2

Divirta-secomissoporumtempoedepoisvolteaqui:).

DjangoGirlsTutorial

23IntroduçãoaoPython

Page 24: Djangogirls Tutorial Pt

Comovocêpodever,oPythonéumaótimacalculadora.Sevocêestáseperguntandooquemaisvocêpodefazer...

StringsQuetaloseunome?Digiteseuprimeironomeentreaspas,dessejeito:

>>>"Ola"

'Ola'

Vocêacaboudecriarsuaprimeirastring!Stringéumsequênciadecaracteresquepodemserprocessadapelocomputador.Astringsempreprecisainiciareterminarcomomesmocaractere.Estepodeseraspasduplas(')ousimples(")-elasdizemaoPythonqueoqueestádentrodelaséumastring.

Stringspodemserjuntadas.Tenteisto:

>>>"Oi"+"Ola"

'OiOla'

Vocêtambémpodemultiplicarstringsporumnúmero:

>>>"Ola"*3

'OlaOlaOla'

Sevocêprecisacolocarumaapóstrofedentrodesuastring,existemduasmaneirasdefazer.

Usandoaspasduplas:

>>>"Correndo'ladeiraabaixo"

"Correndo'ladeiraabaixo"

ouescapandoapóstrofocomumabarrainvertida(``):

>>>"Correndo\'ladeiraabaixo"

"Correndo'ladeiraabaixo"

Legal,hein?Paraverseunomeemletrasmaiúsculas,bastadigitar:

DjangoGirlsTutorial

24IntroduçãoaoPython

Page 25: Djangogirls Tutorial Pt

>>>"Ola".upper()

'OLA'

Vocêacaboudeusarafunçãouppernasuastring!Umafunção(comoupper())éumconjuntodeinstruçõesqueoPythonrealizaemumdeterminadoobjeto("Ola"),semprequevocêchamarporele.

Sevocêquersaberonúmerodeletrasdoseunome,existeumafunçãoparaissotambém!

>>>len("Ola")

3

Seperguntandoporquealgumasvezesvocêchamafunçõescomum.nofimdeumastring(como"Ola".upper())ealgumasvezesvocêprimeirochamaafunçãocolocandoastringnosparênteses?Bem,emalgunscasos,funçõespertencemaobjetos,comoupper(),quesópodeserutilizadaemstrings.Nessecaso,nóschamamosafunçãodemétodo.Outrasvezes,funçõesnãopertencemanadaespecíficoepodemserusadasemdiferentestiposdeobjetos,assimcomolen().Éporissoquenósestamosfornecendo"Ola"comoumparâmetroparaafunçãolen.

Sumário

OK,chegadestrings.Atéagoravocêaprendeusobre:

oprompt-digitarcomandos(códigos)nointerpretadorPythonresultaemrespostasemPythonnúmerosestrings-noPython,númerossãousadosparamatemáticaestringsparaobjetosdetextooperadores-como+e*,combinamvaloresparaproduzirumnovovalorfunções-comoupper()elen(),executamaçõesnosobjetos.

Issoéobásicosobretodasaslinguagensdeprogramaçãoquevocêaprende.Prontoparaalgomaisdifícil?Apostamosquesim!

ErrosVamostentaralgonovo.Podemosobterotamanhodeumnúmerodamesmaformaquepodemosencontrarotamanhodonossonome?Digitelen(304023)epressioneEnter:

DjangoGirlsTutorial

25IntroduçãoaoPython

Page 26: Djangogirls Tutorial Pt

>>>len(304023)

Traceback(mostrecentcalllast):

File"<stdin>",line1,in<module>

TypeError:objectoftype'int'hasnolen()

Temosnossoprimeiroerro!Eledizqueobjetosdotipo"int"(inteiros,apenasnúmeros)nãotêmnenhumcomprimento.Entãooquepodemosfazeragora?Talvezpossamosescrevernossonúmerocomoumastring?Stringstêmumcomprimento,certo?

>>>len(str(304023))

6

Funcionou!Usamosafunçãostrdentrodafunçãolen.str()convertetudoparastrings.

AfunçãostrconverteascoisasemstringsAfunçãointconverteascoisasemnúmerosinteiros

Importante:podemosconverternúmerosemtexto,masnósnãopodemos,necessariamente,convertertextoemnúmeros-oqueint('hello')querdizer?

VariáveisUmconceitoimportantenaprogramaçãoéoconceitodevariáveis.Umavariávelnãoénadamaisdoqueumnomeparaalgumacoisa,detalformaquevocêpossausá-lamaistarde.Osprogramadoresusamessasvariáveisparaguardardados,parafazerseuscódigosmaislegíveiseparanãoterqueselembrarsempreoquealgumascoisassignificam.

Digamosquequeremoscriarumanovavariávelchamadanome:

>>>name="Ola"

Vê?Éfácil!Ésófazer:nomeigualaOla.

Comovocêpercebeu,seuprogramanãoretornounadacomofezanteriormente.Entãocomosabemosqueavariávelrealmenteexiste?SimplesmentedigitenomeetecleEnter:

>>>name

'Ola'

Yippee!Suaprimeiravariável:)!Vocêsemprepodemudaroseuvalor:

DjangoGirlsTutorial

26IntroduçãoaoPython

Page 27: Djangogirls Tutorial Pt

>>>name="Sonja"

>>>name

'Sonja'

Vocêpodeusá-latambémemfunções:

>>>len(name)

5

Incrívelnão?Claro,variáveispodemserqualquercoisa,entãopodemsernúmerostambém!Tenteisso:

>>>a=4

>>>b=6

>>>a*b

24

Mas,esedigitarmosonomeerrado?Vocêconsegueadivinharoqueaconteceria?Vamostentar!

>>>city="Tokyo"

>>>ctiy

Traceback(mostrecentcalllast):

File"<stdin>",line1,in<module>

NameError:name'ctiy'isnotdefined

Umerro!Comovocêpodever,PythontemdiferentestiposdeerroseesteéchamadoNameError.Pythondaráesteerrosevocêtentarusarumavariávelquenãofoidefinidaainda.Sevocêencontraresseerrodepois,vejasenoseucódigosevocênãodigitouonomedeumavariávelerrado.

Brinquecomissoporumtempoevejaoquevocêconseguefazer!

AfunçãoprintTenteisso:

>>>name='Maria'

>>>name

'Maria'

>>>print(name)

Maria

DjangoGirlsTutorial

27IntroduçãoaoPython

Page 28: Djangogirls Tutorial Pt

Quandovocêapenasdigitaname,ointerpretadorPythonrespondecomarepresentaçãocomostringdavariável'name',quesãoasletrasM-a-r-i-a,entreaspassimples.Quandovocêdizprint(name),Pythonvai"imprimir"oconteúdodavariávelnatela,semasaspas,oqueémaispuro.

Comoveremosmaistarde,print()tambéméútilquandoqueremosimprimiralgodentrodefunções,ouquandoqueremosimprimiralgoemváriaslinhas.

ListasAlémdestringseinteiros,oPythontemtodosostiposdiferentesdeobjetos.Vamosapresentarumchamadolista.Listassãoexatamenteoquevocêachaqueelassão:elassãoobjetosquesãolistasdeoutrosobjetos:)

Váemfrenteecrieumalista:

>>>[]

[]

Sim,estaéumalistavazia.Nãoémuito,nãoé?Vamoscriarumalistadosnúmerosdaloteria.Comonãoqueremosficarrepetindoocódigotodootempovamoscriarumavariávelparaela:

>>>lottery=[3,42,12,19,30,59]

Tudocerto,nóstemosumalista!Oquepodemosfazercomisso?Vamosverquantosnúmerosdeloteriaexistemnestalista.Vocêtemideiadequalfunçãodeveusarparaisso?Vocêjásabedisso!

>>>len(lottery)

6

Sim!len()podetedaronúmerodeobjetosquefazempartedeumalista.Umamãonaroda,não?Vamosorganizarissoagora:

>>>lottery.sort()

Issonãoretornanada,apenastrocaaordememqueosnúmerosaparecemnalista.Vamosimprimirissooutravezeveroqueacontece:

DjangoGirlsTutorial

28IntroduçãoaoPython

Page 29: Djangogirls Tutorial Pt

>>>print(lottery)

[3,12,19,30,42,59]

Comovocêpodever,osnúmerosnanossalistaestãoordenadosdomenorparaomaior.Parabéns!

Talvezagentequeirainverteressaordem?Vamosfazerisso!

>>>lottery.reverse()

>>>print(lottery)

[59,42,30,19,12,3]

Molezané?Sevocêquiseradicionaralgumacoisaàsualista,vocêpodefazeristodigitandooseguintecomando:

>>>lottery.append(199)

>>>print(lottery)

[59,42,30,19,12,3,199]

Sevocêquisermostrarapenasoprimeironúmerovocêpodeusarindices.Umíndiceéumnúmeroquedizondeumitemdalistaestá.Oscomputadoresgostamdeiniciaracontagempor0,entãooprimeiroobjetotemíndice0,opróximotemíndice1eporaívai.Tenteisso:

>>>print(lottery[0])

59

>>>print(lottery[1])

42

Comovocêpodever,vocêpodeacessardiferentesobjetosnasualistausandoonomedalistaeoíndicedoobjetodentrodoscolchetes.

Pordiversãoextra,tentealgunsoutrosíndices:6,7,1000,-1,-6ou-1000.Vejasevocêconseguepreveroresultadoantesdetentarocomando.Osresultadosfazemsentido?

VocêpodeencontrarumalistadetodososmétodosdisponíveisnestecapítulonadocumentaçãodoPython:https://docs.python.org/3/tutorial/datastructures.html

DicionáriosUmdicionárioésemelhanteaumalista,masvocêpodeacessarvaloresatravésdeumachaveaoinvésdeumíndice.Umachavepodeserqualquerstringounúmero.Asintaxeparadefinirumdicionáriovazioé:

DjangoGirlsTutorial

29IntroduçãoaoPython

Page 30: Djangogirls Tutorial Pt

>>>{}

{}

Issomostraquevocêacaboudecriarumdicionáriovazio.Hurra!

Agora,tenteescreveroseguintecomando(tentesubstituircomassuasprópriasinformaçõestambém):

>>>participant={'name':'Ola','country':'Poland','favorite_numbers':[7,42,92]}

Comessecomando,vocêacaboudecriarumavariávelchamadaparticipantcomtrêsparesdechave-valor:

Achavenomeapontaparaovalor'Ola'(umobjetostring),paisapontapara'Polonia'(outrastring),enumeros_favoritosapontampara[7,42,92](umalistcomtrêsnúmerosnela).

Vocêpodechecaroconteúdodechavesindividuaiscomasintaxe:

>>>print(participant['name'])

Ola

Veja,ésimilaraumalista.Masvocênãoprecisalembraroíndice-apenasonome.

OqueacontecesepedirmosaoPythonovalordeumachavequenãoexiste?Vocêconsegueadivinhar?Vamostentaredescobrir!

>>>participant['age']

Traceback(mostrecentcalllast):

File"<stdin>",line1,in<module>

KeyError:'age'

Olha,outroerro!EsseéumKeyError.Pythonébastanteprestativoetedizqueachave'age'nãoexistenonessedicionário.

Quandousarumdicionarioouumalista?Bem,umbompontopararefletir.Penseemumasoluçãoantesdeolhararespostanapróximalinha.

Vocêprecisadeumasequênciaordenadadeitens?Useumalist.Vocêprecisaassociarvalorescomchaves,assimvocêpodeprocurá-loseficientemente(pelachave)maistarde?Useumdictionary.

DjangoGirlsTutorial

30IntroduçãoaoPython

Page 31: Djangogirls Tutorial Pt

Dicionários,comolistas,sãomutáveis,ouseja,quepodemsermudadosdepoisquesãocriados.Vocêpodeadicionarnovosparesdechave/valorparaodicionárioapóssuacriação,como:

>>>participant['favorite_language']='Python'

Comoaslists,usarométodolen()emdicionáriosretornaonúmerodepareschave-valornodicionario.Váemfrenteedigiteocomando:

>>>len(participant)

4

Esperoqueagorafaçasentidoatéagora.:)Prontaparamaisdiversãocomdicionários?Pulenapróximalinhaparacoisasincríveis.

Vocêpodeusarocomandodelparadeletarumitemnodicionario.Digamos,sevocêquerexcluiraentradacorrespondenteachave'favorite_numbers',bastadigitaroseguintecomando:

>>>delparticipant['favorite_numbers']

>>>participant

{'country':'Poland','favorite_language':'Python','name':'Ola'}

Comovocêpodevernoretorno,oparchave-valorcorrespondenteàchave'favorite_numbers'foiexcluído.

Alémdissovocêpodemudarovalorassociadocomumachavejácriadanodicionário.Digite:

>>>participant['country']='Germany'

>>>participant

{'country':'Germany','favorite_language':'Python','name':'Ola'}

Comovocêpodever,ovalordachave'country'foialteradode'Poland'para'Germany'.:)Emocionante?Hurra!Vocêacaboudeaprenderoutracoisaincrível.

Sumário

Incrível!Agoravocêsabemuitosobreprogramação.Nestaúltimapartevocêaprendeusobre:

erros-agoravocêsabecomolereentendererrosqueaparecemseoPythonnão

DjangoGirlsTutorial

31IntroduçãoaoPython

Page 32: Djangogirls Tutorial Pt

entenderumcomandoquevocêdeuvariáveis-nomesparaobjetosquepermitemvocêprogramarfacilmenteedeixarseucódigomaislegívellistas-listasdeobjetosarmazenadosemumaordemespecíficadicionários-objetosarmazenadoscomopareschave-valor

Empolgado(a)paraopróximopasso?:)

ComparecoisasGrandepartedaprogramaçãoconsisteemcompararcoisas.Oqueémaisfácildecomparar?Números,éclaro.Vamosvercomoissofunciona:

>>>5>2

True

>>>3<1

False

>>>5>2*2

True

>>>1==1

True

>>>5!=2

True

DemosaoPythonalgunsnúmerosparacomparar.Comovocêpodever,Pythonpodecompararnãosónúmerosmastambémresultadosdemétodos.Legal,hein?

Vocêestáseperguntandoporquecolocamosdoissinaisdeigual==ladoaladoparacompararseosnúmerossãoiguais?Nósusamosumúnico=paraatribuirvaloresavariáveis.Vocêsempre,sempreprecisacolocardois==sequiserverificarseascoisassãoiguais.Tambémépossívelafirmarqueascoisassãodesiguaisentresi.Paraisso,usamososímbolo!=,conformemostradonoexemploacima.

DêaoPythonmaisduastarefas:

>>>6>=12/2

True

>>>3<=2

False

>e<sãofáceis,masoque>=e<=significam?Leiaelesdaseguinteforma:

x>ysignifica:xémaiorqueyx<ysignifica:xémenorquey

DjangoGirlsTutorial

32IntroduçãoaoPython

Page 33: Djangogirls Tutorial Pt

x<=ysignifica:xémenorouigualayx>=ysignifica:xémaiorouigualay

Fantástico!Quermais?Tenteisto:

>>>6>2and2<3

True

>>>3>2and2<1

False

>>>3>2or2<1

True

VocêpodedaraoPythonquantosnúmerosparacompararquantovocêquiser,eelevaitedarumaresposta!Espertinho,certo?

and-sevocêusarooperadorand,ambasascomparaçõesterãoqueserverdadeirasparaquetodoocomandosejaverdadeiroor-sevocêusarooperadoror,apenasumadascomparaçõesprecisaserverdadeiraparaqueocomandotodosejaverdadeiro

Jáouviuaexpressão"compararmaçãscomlaranjas"?VamostentaroequivalenteemPython:

>>>1>'django'

Traceback(mostrecentcalllast):

File"<stdin>",line1,in<module>

TypeError:unorderabletypes:int()>str()

Aquivemosqueassimcomonaexpressão,Pythonnãoécapazdecompararumnúmero(int)eumastring(`str</0)>.Emvezdisso,elemostrouumTypeErrorenosdissequeosdoistiposnãopodemsercomparadosjuntos.</p>

BooleanoAcidentalmente,vocêaprendeusobreumnovotipodeobjetoemPython.Échamadodebooleano--eprovavelmenteotipomaisfácilqueexiste.

Existemapenasdoisobjetosbooleanos:-True(verdadeiro)-False(falso)

MasparaoPythonentenderisso,vocêprecisasempreescreverTrue(primeiraletramaiúscula,comorestodasletrasemminúsculo).true,TRUE,tRUEnãovaifuncionar--sóTrueécorreto.(OmesmoseaplicaaoFalse,claro.)

Booleanospodemservariáveistambém!Veja:

DjangoGirlsTutorial

33IntroduçãoaoPython

Page 34: Djangogirls Tutorial Pt

>>>a=True

>>>a

True

Vocêtambémpodefazerdessejeito:

>>>a=2>5

>>>a

False

Pratiqueedivirta-secomosvaloresbooleanos,tentandoexecutarosseguintescomandos:

TrueandTrue

FalseandTrue

Trueor1==1

1!=2

Parabéns!Booleanossãoumdosrecursosmaisinteressantesnaprogramação,evocêacaboudeaprendercomousá-los!

Salvá-lo!Atéagoranósescrevemostodonossocódigoemuminterpretadorpython,quenoslimitaaumalinhadecódigoemummomento.Programasnormaissãosalvosemarquivoseexecutadospelonossointerpretadordelinguagemdeprogramaçãooucompilador.AtéagorajácorremosnossosprogramasdeumalinhadecadaveznointerpretadorPython.Nósvamosprecisardemaisdeumalinhadecódigoparaaspróximastarefas,entãoprecisaremosrapidamente:

SaídadointerpretadorPythonAbraseueditordecódigodesuaescolhaSalvaralgumcódigoemumnovoarquivodepythonExecutá-lo!

ParasairdointerpretadorPythonqueestamosusando,simplesmentedigiteo~exit()~função:

>>>exit()

$

Issovaicolocá-lonopromptdecomando.

DjangoGirlsTutorial

34IntroduçãoaoPython

Page 35: Djangogirls Tutorial Pt

Anteriormente,nósescolhemosumeditordecódigodaseçãodoeditordecódigo.Nósprecisamosabriroeditoragoraeescreveralgumcódigoemumnovoarquivo:</p>

print('Hello,Djangogirls!')

NotaVocêdeveobservarqueumadascoisasmaislegaissobreeditoresdecódigo:cores!NoconsoledoPython,tudoeradamesmacor,masagoravocêdeveverqueafunçãodeImprimiréumacordiferentedasequênciadecaracteresnoseuinterior.Issoéchamadode"realcedesintaxe",eéumaajudamuitoútilquandoestáprogramando.Percebaacordascoisasevocêvaiobterumadicaparaquandovocêesquecerdefecharumaseqüênciadecaracteres,oufazerumerrodedigitaçãoemumnomedepalavra-chave(comodefemumafunção,queveremosabaixo).Estaéumadasrazõespelasquaisquenósusamosumeditordecódigo:)

Obviamente,vocêéumdesenvolvedorpythonbastanteexperienteagora,entãosinta-selivreparaescreverumcódigoquevocêaprendeuhoje.

Agoratemosdesalvaroarquivoedêumnomedescritivo.Vamoschamaroarquivopython_intro.pyesalve-oemseudesktop.Podemosnomearoarquivotudooquequisermos,oimportanteaquiétercertezaqueoarquivoterminanopy,istodiznossocomputador,queéumarquivoexecutáveldepythonePythonpodeexecutá-lo.

Comoarquivosalvo,éhoradeexecutá-lo!Usandoashabilidadesquevocêaprendeunaseçãodelinhadecomando,useoterminalaltereosdiretóriosparaodesktop.

EmumMac,ocomandoseráparecidocomisto:

cd/Users/<your_name>/Desktop

NoLinux,seráassim(apalavra"Desktop"podesertraduzidoparaseuidioma):

cd/home/<your_name>/Desktop

Enowindows,vaiserassim:

cdC:\Users\<your_name>\Desktop

Sevocêficarpreso,sópedirajuda.

e,emseguida,usaroPythonparaexecutarocódigonoarquivoassim:

DjangoGirlsTutorial

35IntroduçãoaoPython

Page 36: Djangogirls Tutorial Pt

$python3python_intro.py

Hello,Djangogirls!

Tudobem!Vocêacaboudeseuprimeiroprogramaempythonquefoisalvoemumarquivo.Mesintoótimo?

Vocêpodeagorapassarparaumaferramentaessencialnaprogramação:

if...elif...elseMuitascoisasnocódigosópodemserexecutadassedeterminadascondiçõesforematendidas.ÉporissoqueoPythontemalgumacoisachamadadeclaraçãoif.

Substituaocódigonoarquivopython_intro.pyparaisto:

if3>2:

Sesalvouesteeelefoiexecutado,nósveríamosumerrocomoeste:

$python3python_intro.py

File"python_intro.py",line2

^

SyntaxError:unexpectedEOFwhileparsing

Pythonesperaquefornecemosmaisinstruçõesqueserãosupostamenteexecutadascasoacondição3>2venhaaserverdadeira(ouTruenessecaso).VamostentarfazeroPythonimprimir"Itworks!".Altereoseucódigonoseuarquivopython_intro.pyparaisto:

if3>2:

print('Itworks!')

Observecomopodemosterrecuadoapróximalinhadecódigopor4espaços?PrecisamosfazerissoparaquePythonsabequecódigoaserexecutadoseocódigoresultaemtrue.Vocêpodefazerumespaço,masquasetodososprogramadoresPythonfazemcom4paratornarascoisasumolharpuro.Umúnicotabtambémvaicontarcomo4espaços.

Salvá-loeexecutenovamente:

$python3python_intro.py

Itworks!

DjangoGirlsTutorial

36IntroduçãoaoPython

Page 37: Djangogirls Tutorial Pt

Esenão?

Nosexemplosanteriores,ocódigofoiexecutadosomentequandoascondiçõeseramverdade.MasoPythontambémteminstruçõeselifeelse:

if5>2:

print('5isindeedgreaterthan2')

else:

print('5isnotgreaterthan2')

Quandoforexecutadoiráimprimir:

$python3python_intro.py

5emaiorque2

Se2forumnúmeromaiordoque5,entãoosegundocomandoseráexecutado.Fácil,né?Vamosvercomofuncionaoelif:

name='Sonja'

ifname=='Ola':

print('HeyOla!')

elifname=='Sonja':

print('HeySonja!')

else:

print('Heyanonymous!')

eexecutado:

$python3python_intro.py

HeySonja!

Viuoqueaconteceu?

Sumário

Nosúltimostrêsexercíciosvocêaprendeu:

compararascoisas-emPython,vocêpodecompararascoisasusandoosoperadores>,>=,==,<=,<eoand,orBooleano-umtipodeobjetoquesótemumdosdoisvalores:TrueouFalseSalvandoarquivos-armazenamentodecódigoemarquivosassimvocêpodeexecutarprogramasmaiores.if...elif...else-instruçõesquepermitemquevocêexecuteocódigosomentese

DjangoGirlsTutorial

37IntroduçãoaoPython

Page 38: Djangogirls Tutorial Pt

determinadascondiçõesforematendidas.Éhoradaúltimapartedestecapítulo!

Suasprópriasfunções!Selembradefunçõescomolen()quevocêpodeexecutarnoPython?Bem,boasnotícias,agoravocêvaiaprenderaescreversuasprópriasfunções!

UmafunçãoéumsequênciadeinstruçõesqueoPythondeveexecutar.CadafunçãoemPythoncomeçacomapalavra-chavedef,seguidodeumnomeparaafunçãoeopcionalmenteumalistadeparâmetros.Vamoscomeçarcomumafunçãosimples.Substituaocódigonopython_intro.pycomoseguinte:

defhi():

print('Hithere!')

print('Howareyou?')

hi()

Ok,nossaprimeirafunçãoestápronta!

Vocêpodeseperguntarporqueescrevemosonomedafunçãonaparteinferiordoarquivo.IstoéporquePythonlêoarquivoeexecuta-lodecimaparabaixo.Então,parausaranossafunção,temosre-escrevê-lonaparteinferior.

Vamosexecuta-loagoraeveroqueacontece:

$python3python_intro.py

Hithere!

Howareyou?

Issofoifácil!Vamosconstruirnossaprimeirafunçãocomparâmetros.Usaremosoexemploanterior-umafunçãoquediz'hi'paraquemoexecuta-comumname:

defhi(name):

Comovocêpodever,agorademosumparâmetrochamadonameparanossafunção:

DjangoGirlsTutorial

38IntroduçãoaoPython

Page 39: Djangogirls Tutorial Pt

defhi(name):

ifname=='Ola':

print('HiOla!')

elifname=='Sonja':

print('HiSonja!')

else:

print('Hianonymous!')

hi()

Comovocêpodever,nósprecisamoscolocardoisespaçosantesdafunçãoprint,porqueifprecisasaberoquedeveacontecerquandoacondiçãoforatendida.Vamosvercomoissofuncionaagora:

$python3python_intro.py

Traceback(mostrecentcalllast):

File"python_intro.py",line10,in<module>

hi()

TypeError:hi()missing1requiredpositionalargument:'name'

Oops,umerro.Felizmente,Pythonnosforneceumamensagemdeerrobastanteútil.Eladizqueafunçãohi()(aquelaquedeclaramos)temumargumentoobrigatório(chamadoname)equenósesquecemosdepassá-loaochamarafunção.Vamoscorrigi-lonaparteinferiordoarquivo:

hi("Ola")

eexecutenovamente:

$python3python_intro.py

HiOla!

Esemudarmosonome?

hi("Sonja")

eexecutá-lo:

$python3python_intro.py

HiSonja!

DjangoGirlsTutorial

39IntroduçãoaoPython

Page 40: Djangogirls Tutorial Pt

Agora,oqueachaquevaiacontecersevocêescreveroutronomelá?(NãoOlaouSonja)Experimentá-loeversevocêestácerto.Eledeveimprimiristo:

Hianonymous!

Istoéincrível,não?Dessamaneiravocênãoprecisaserepetir(DRY-don'trepeatyourself)cadavezqueformudaronomedapessoaqueafunçãopretendecumprimentar.Eéexatamenteporissoqueprecisamosdefunções-vocênuncaquerrepetirseucódigo!

Vamosfazeralgomaisinteligente..--existemmaisquedoisnomes,eescreverumacondiçãoparacadaumseriadifícil,certo?

defhi(name):

print('Hi'+name+'!')

hi("Rachel")

Vamoschamarocódigoagora:

$python3python_intro.py

HiRachel!

Parabéns!Vocêacaboudeaprenderacriarfunções:)!

LaçosJáéaúltimaparte.Foirápido,não?:)

Comomencionamos,osprogramadoressãopreguiçosos,nãogostamderepetirasmesmascoisas.Programaçãofalasobrecomoautomatizarascoisas,entãonãoqueremoscumprimentarcadapessoapeloseunomemanualmente,certo?Éaíondeoslaçosvemacalhar.

Aindaselembradaslistas?Vamosfazerumalistadegarotas:

girls=['Rachel','Monica','Phoebe','Ola','You']

Queremoscumprimentartodaselaspelosseusnomes.Temosafunçãohiparafazerisso,entãovamosusá-laemumloop:

fornameingirls:

DjangoGirlsTutorial

40IntroduçãoaoPython

Page 41: Djangogirls Tutorial Pt

O~for~declaraçãosecomportadamesmaformaparao~if~declaração,códigoabaixoessesdoisprecisamserrecuadosquatroespaços.

Aquiestáocódigocompletoqueserásalvonoarquivo:

defhi(name):

print('Hi'+name+'!')

girls=['Rachel','Monica','Phoebe','Ola','You']

fornameingirls:

hi(name)

print('Nextgirl')

equandoexecutá-lo:

$python3python_intro.py

HiRachel!

Nextgirl

HiMonica!

Nextgirl

HiPhoebe!

Nextgirl

HiOla!

Nextgirl

HiYou!

Nextgirl

Comovocêpodever,tudooquevocêvaicolocardentrodeumainstruçãoforcomespaçoserárepetidoparacadaelementodalistagirls.

Vocêtambémpodeusaroforemnúmerosusandoafunçãorange:

foriinrange(1,6):

print(i)

Queiriaimprimir:

1

2

3

4

5

rangeéumafunçãoquecriaumalistadenúmerosqueseseguemumapósooutro(essesnúmerossãodadosporvocêcomoparâmetros).

DjangoGirlsTutorial

41IntroduçãoaoPython

Page 42: Djangogirls Tutorial Pt

NotequeosegundodessesdoisnúmerosnãoestáincluídonalistaqueoPythonmostrou(emrange(1,6),contade1a5,maso6nãoéincluído).

SumárioÉisso.Vocêétotalmentedemais!Nãoétãofácil,entãovocêdevesesentirorgulhosodesimesmo.Estamosdefinitivamenteorgulhososdevocêporterchegadoatéaqui!

Talvezvocêqueirabrevementefazeralgomais-espreguiçar,andarumpouco,descansarosolhos-antesdeirparaopróximocapítulo.:)

DjangoGirlsTutorial

42IntroduçãoaoPython

Page 43: Djangogirls Tutorial Pt

OqueéDjango?Djangoéumframeworkgratuitoedecódigoabertoparaacriaçãodeaplicaçõesweb,escritoemPython.Éumframeworkweb,ouseja,éumconjuntodecomponentesqueajudaadesenvolversitesdeformamaisrápidaemaisfácil.

Veja,quandovocêestáconstruindoumsite,vocêsempreprecisaumconjuntosimilardecomponentes:umamaneiradelidarcomaautenticaçãodousuário(inscrever-se,realizarlogin,realizarlogout),paineldegerenciamentoparaoseusite,formulários,uploaddearquivos,etc.

Felizmenteparavocê,hámuitotempo,outraspessoasnotaramvariassemelhançasnosproblemasenfrentadospelosdesenvolvedoreswebquandoestãocriandoumnovosite,entãoelesuniram-seecriaramosframeworks(Djangoéumdeles)quelhedãocomponentesprontos,quevocêpodeusar.

Frameworksexistemparasalvá-lodeterquereinventararodaeajudamaaliviarasobrecargaquandovocêestáconstruindoumnovosite.

Porquevocêprecisadeumframework?ParaentenderoqueDjangoénaverdade,precisamosolharmaisdepertoosservidores.Aprimeiracoisaéqueoservidorprecisasaberquevocêquerparaservi-loumapáginadaWeb.

Imagineumacaixadecorreio(porta)queémonitoradaporcartasrecebidas(requisição).Issoéfeitoporumservidorweb.Oservidorweblêacartaeenviaumarespostacomumapáginaweb.Mas,quandovocêquerenviaralgumacoisavocêprecisaterumconteúdo.EoDjangoéaquiloquevailheajudaracriaresseconteúdo.

Oqueacontecequandoalguémsolicitaumsitedoseuservidor?QuandochegaumarequisiçãoparaoservidorwebelaépassadaparaoDjangoquetentadescobrirdoqueelasetrata.Primeiroelepegaumendereçowebetentadescobriroquefazer.EssaparteéfeitapelourlresolverdoDjango.(NotequeoendereçodeumsitesechamaURL-UniformResourceLocator,emportuguêsLocalizadordeRecursosUniforme,dessaformaonomeurlresolver,ouresolvedordeurls,fazsentido).Issonãoémuito

DjangoGirlsTutorial

43OqueéDjango?

Page 44: Djangogirls Tutorial Pt

inteligente-levaàumalistadepadrõesetentacorresponderaURL.ODjangoverificapadrõesdecimaparabaixoesealgoécorrespondido,passaasolicitaçãoparaafunçãoassociada(queéchamadaview).

Imagineumcarteirocomumacarta.Elaestáandandopelaruaeverificacadanúmerodecasacomaqueestánacarta.Seelecorresponder,elacolocaacartalá.Éassimquefuncionaourlresolver!

Todasascoisasinteressantessãofeitasdentrodaview:podemosdarumaolhadanobancodedadosparaprocuraralgumasinformações.Talvezousuárioqueiramudaralgonosdados?Comoumacartadizendo:"Porfavormudeadescriçãodomeuemprego."-aviewchecasevocêtempermissãoparafazerissoeentãoatualizaadescriçãodoempregopravocê,enviandoemseguidaumamensagem:"Feito!".EntãoaviewgeraumarespostaeoDjangopodeenviá-laparaonavegadordocliente.

Claro,adescriçãoacimaémuitosimplificada,masvocênãoprecisasaberdetalhestécnicosainda.Terumaideiageraljáésuficiente.

Entãoemvezdemergulharemmuitosdetalhes,nóssimplesmentevamoscomeçarcriandoalgocomoDjangoeaprenderemostodaaspartesimportantesaolongodocaminho!

DjangoGirlsTutorial

44OqueéDjango?

Page 45: Djangogirls Tutorial Pt

InstalaçãodoDjangoPartedestecapítuloébaseadonostutoriaisdoGeekGirlsCarrots(http://django.carrots.pl/).

Partedestecapítuloébaseadonodjango-marcadortutoriallicenciadosobreCreativeCommonsAttribution-ShareAlike4.0InternationalLicense.Otutorialdodjango-marcadoréprotegidopordireitosautoraisporMarkusZapke-Gründemannetal.

AmbientevirtualAntesdeinstalarmosoDjango,nósiremosinstalarumaferramentaextremamenteútilqueiráajudaramanterseuambientededesenvolvimentoarrumadoemseucomputador.Épossívelignorarestepasso,maséaltamenterecomendadonãocomeçarcomamelhorconfiguração,evitandoproblemasadiante!

Então,vamoscriarumambientevirtual(tambémchamadoumvirtualenv).IssoisolarásuaconfiguraçãoPython/Djangoemumabaseporprojeto,significaquequaisquermudançasquefizeremumwebsitenãoafetaráquaisqueroutrasaplicaçõesqueestiverdesenvolvendoaparte.Arrumado,certo?

Tudooquevocêprecisafazeréencontrarumdiretórionoqualvocêdesejacriarovirtualenv;SeudiretórioHome,porexemplo.NoWindowspodeparecercomoC:\Usuário\Nome(ondeNomeéonomedoseulogin).

Paraestetutorialusaremosumnovodiretóriodjangogirlsdoseudiretóriohome:

mkdirdjangogirls

cddjangogirls

Nósvamosfazerumvirtualenvchamadomeuenv.Oformatogeraldessecomandoé:

python3-mvenvmyvenv

Windows

Paracriarumnovovirtualenv,vocêprecisaabriroconsole(Nósfalamossobreissoalgunscapítulosatrás,lembra-se?)eexecutarC:\Python34\python-mvenvmyvenv.Seráalgoparecidocomisto:

DjangoGirlsTutorial

45InstalaçãodoDjango

Page 46: Djangogirls Tutorial Pt

C:\Usuário\Nome\djangogirls>C:\Python34\python-mvenvmyvenv

ondeC:\Python34\pythonéodiretórioemquevocêpreviamenteinstalouPythonemyvenvéonomedasuavirtualenv.Vocêpodeusarqualqueroutronome,massempreuseminúsculasesemespaços,acentosoucaracteresespeciais.Tambéméumaboaideiamanteronomecurto-vocêiráreferenciarmuitoaele!

LinuxeOSX

CriarumvirtualenvtantonoLinuxcomoOSXésimplescomoexecutarpython3-mvenvmyvenv.Seráalgoparecidocomisto:

~/djangogirls$python3-mvenvmyvenv

myvenvéonomedasuavirtualenv.Vocêpodeusarqualqueroutronome,maspermaneçaemcaixabaixa(minúsculas)enãouseespaçosentreosnomes.Tambéméumaboaideiamanteronomecurto-vocêiráreferenciarmuitoaele!

NOTA:IniciaroambientevirtualnoUbuntu14.04assimretornaráoseguinteerro:

Error:Command'['/home/eddie/Slask/tmp/venv/bin/python3','-Im','ensurepip','--upgrade','--default-pip']'returnednon-zeroexitstatus1

Paracontornaresseproblema,useocomandovirtualenv.

~/djangogirls$sudoapt-getinstallpython-virtualenv

~/djangogirls$virtualenv--python=python3.4myvenv

TrabalhandocomovirtualenvOcomandoacimacriaráumdiretóriochamadomyvenv(ousejaonomequevocêescolheu)quecontémonossoambientevirtual(basicamenteumconjuntodediretóriosearquivos).Tudooquequeremosporenquantoéiniciá-loexecutando:

C:\Usuário\Nome\djangogirls>myvenv\Scripts\activate

noWindows,ou:

~/djangogirls$sourcemyvenv/bin/activate

DjangoGirlsTutorial

46InstalaçãodoDjango

Page 47: Djangogirls Tutorial Pt

noOSXenoLinux.

Lembre-sedesubstituirmyvenvcomseunomeescolhidodovirtualenv!

NOTE:àsvezessource(fonte)podenãoestardisponível.Nessescasos,tentefazerissoemvezdisso:

~/djangogirls$.myvenv/bin/activate

Vocêvaisaberquetemumvirtualenvfuncionandoquandoveropromptnoseuconsoleseparecercom:

(myvenv)C:\Usuário\Nome\djangogirls>

ou:

(myvenv)~/djangogirls$

Percebaqueoprefixo(myvenv)aparece!

Aotrabalhardentrodeumambientevirtual,pythoniráautomaticamentesereferiraversãocorretaparaquepossautilizarpythonemvezdepython3.

Ok,nóstemostodasasdependênciasimportantesnolugar.FinalmentepodemosinstalaroDjango!

InstalandooDjangoAgoraquevocêtemasuavirtualenviniciado,vocêpodeinstalarDjangousandopip.Noconsole,executepipinstalldjango==1.8.5(Percebaqueusamosumduplosinaldeigual:==).

(myvenv)~$pipinstalldjango==1.8.5

Downloading/unpackingdjango==1.8.5

Installingcollectedpackages:django

Successfullyinstalleddjango

Cleaningup...

noWindows

DjangoGirlsTutorial

47InstalaçãodoDjango

Page 48: Djangogirls Tutorial Pt

SevocêreceberumerroaochamaropipnaplataformaWindowsporfavor,verifiqueseocaminhodoprojetocontémespaços,acentosoucaracteresespeciais(exemplo,C:\Users\UserName\djangogirls).Sesimporfavormovaparaoutrolugarsemespaços,acentosoucaracteresespeciais(sugestãoé:C:\djangogirls).Apósamudança,porfavortentenovamenteocomandoacima.

NoLinux

SevocêreceberumerroaochamarpipnoUbuntu12.04porfavorexecutepython-mpipinstall-U--force-reinstallpipparacorrigirainstalaçãodopipnovirtualenv.

Éisso!Agoravocêestá(finalmente)prontoparacriarumaaplicaçãoDjango!

DjangoGirlsTutorial

48InstalaçãodoDjango

Page 49: Djangogirls Tutorial Pt

SeuprimeiroprojetoDjango!PartedestecapítuloébaseadonostutoriaisdoGeekGirlsCarrots(http://django.carrots.pl/).

Partedestecapítuloébaseadonodjango-marcadortutoriallicenciadosobreCreativeCommonsAttribution-ShareAlike4.0InternationalLicense.Otutorialdodjango-marcadoréprotegidopordireitosautoraisporMarkusZapke-Gründemannetal.

Nósvamoscriarumblogsimples!

Oprimeiropassoparacriá-loécomeçarumnovoprojetodeDjango.Basicamente,istosignificaquevamosexecutaralgunsscriptsfornecidospeloDjangoqueirácriaroesqueletodeumprojetoDjangoparanós:umbandodediretóriosearquivosqueusaremosmaistarde.

OsnomesdealgunsarquivosediretóriossãomuitoimportantesparaoDjango.Nãorenomeieosarquivosqueestamosprestesacriar.Moverparaumlugardiferentetambémnãoéumaboaidéia.Djangoprecisamanterumadeterminadaestruturaparasercapazdeencontrarcoisasimportantes.

Lembre-sequetudonovirtualenv.Sevocênãovêumprefixo(myvenv)emseuconsole,vocêprecisaativarovirtualenv.NósexplicamoscomofazerissonocapítuloinstalaçãodoDjangonapartetrabalhandocomvirtualenv.Vocêpodefazerissodigitandooseguintecomando:myvenv\Scripts\activatenoWindowsoumyvenv/bin/activatenoMacOS/Linux.

NotaVerifiquequevocêincluiuoponto(.)nofinaldocomando,éimportanteporquedizoscriptparainstalaroDjangoemseudiretórioatual.

Noconsole,vocêdeveexecutar(Lembre-sedequevocênãopodedigitar~/djangogirls$(myvenv),OK?):

(myvenv)~/djangogirls$django-adminstartprojectmysite.

noWindows:

(myvenv)C:\Users\Name\djangogirls>pythonmyvenv\Scripts\django-admin.pystartprojectmysite.

Django-adminéumscriptqueirácriarosdiretóriosearquivosparavocê.Agora,vocêdeveterumdiretórioestruturaqueseparececomisso:

DjangoGirlsTutorial

49Criandoumprojeto

Page 50: Djangogirls Tutorial Pt

djangogirls

├───manage.py

└───mysite

settings.py

urls.py

wsgi.py

__init__.py

manage.pyéumscriptqueajudacomagestãodosite.Comissoseremoscapazesdeiniciarumservidordewebnonossocomputadorseminstalarnada,entreoutrascoisas.

Oarquivosettings.pycontémaconfiguraçãodoseusite.

Lembraquandofalamossobreumcarteiroverificandoondeentregarumacarta?arquivourls.pycontémumalistadospadrõesusadosporurlresolver.

Vamosignorarosoutrosarquivosporagora-nósnãovamosmudá-los.Aúnicacoisaalembrarénãoexcluí-losporacidente!

ConfigurandoVamosfazeralgumasalteraçõesnomysite/settings.py.Abraoarquivousandooeditordecódigoquevocêinstalouanteriormente.

Seriabomterahoracorretanonossosite.Váparaa<wikipediatimezoneslistecopieseufusohorário.(porexemplo.Europa/Berlim)

Emsettings.py,localizealinhaquecontémTIME_ZONEemodifiqueparaescolherseuprópriofusohorário:

TIME_ZONE='Europe/Berlin'

Modifique"Europa/Berlim",conformeocaso

Nóstambémprecisaramosadicionarumcaminhoparaarquivosestáticos(nósvamosdescobrirtudosobrearquivosestáticoseCSSmaistardenotutorial).DesçaatéofinaldoarquivoelogoabaixodaentradaSTATIC_URL,adicioneumnovoumchamadoSTATIC_ROOT:

STATIC_URL='/static/'

STATIC_ROOT=os.path.join(BASE_DIR,'static')

DjangoGirlsTutorial

50Criandoumprojeto

Page 51: Djangogirls Tutorial Pt

InstalaçãodeumbancodedadosHáummontedesoftwaredebancodedadosdiferentequepodearmazenardadosparaoseusite.Nósvamosusaropadrão,sqlite3.

Istojáestáconfiguradonestapartedoseuarquivomysite/settings.py:

DATABASES={

'default':{

'ENGINE':'django.db.backends.sqlite3',

'NAME':os.path.join(BASE_DIR,'db.sqlite3'),

}

}

Paracriarumbancodedadosparaonossoblog,vamosfazeroseguintenoconsole.Digite:pythonmanage.pymigrate(precisamosestarnodiretórioquecontémoarquivomanage.pydjangogirls).Seissodercerto,vocêdeveveralgocomoisto:

(myvenv)~/djangogirls$pythonmanage.pymigrate

Operationstoperform:

Applyallmigrations:admin,contenttypes,auth,sessions

Runningmigrations:

Applyingcontenttypes.0001_initial...OK

Applyingauth.0001_initial...OK

Applyingadmin.0001_initial...OK

Applyingsessions.0001_initial...OK

Eestápronto!Horadeiniciaroservidorwebeversenossositeestáfuncionando!

Vocêprecisaestarnodiretórioquecontémoarquivomanage.py(odiretóriodjangogirls).Noconsole,nóspodemosiniciaroservidorwebexecutandoopythonmanage.pyrunserver:

(myvenv)~/djangogirls$pythonmanage.pyrunserver

Agoratudoquevocêprecisafazeréverificarseseusiteestásendoexecutado-abraseunavegador(Firefox,Chrome,Safari,InternetExplorerouoquevocêusa)edigiteoendereço:

http://127.0.0.1:8000/

Oservidorwebvaiassumirseupromptdecomandoatévocêpará-lo:paradigitarmaiscomandosouabrirumanovajaneladoterminal(enãoseesqueçadeativarseuvirtualenvneletambém),oupararoservidordeweb,alternandodevoltaparaajanelanaqualestá

DjangoGirlsTutorial

51Criandoumprojeto

Page 52: Djangogirls Tutorial Pt

executandoepressionandoCTRL+C-botõesdecontroleeCjuntos(noWindows,vocêpodeterquepressionarCtrl+Break).

Parabéns!Vocêcriouseuprimeirositeeoexecutouusandoumservidordeweb!Nãoéimpressionante?

Prontoparaopróximopasso?Estánahoradecriaralgumconteúdo!

DjangoGirlsTutorial

52Criandoumprojeto

Page 53: Djangogirls Tutorial Pt

ModelosdoDjangoAgoraoquenósqueremoscriaréalgoquearmazenetodosospostsnonossoblog.Masparafazerissoprecisamosaprenderumpoucomaissobrecoisaschamadasobjetos.

ObjetosExisteumconceitonaprogramaçãochamadoProgramaçãoOrientadaàObjetos(POO).Aideiaéqueaoinvésdeescrevertudocomoumachatasequênciadeinstruçõesdeprogramaçãopodemosmodelarascoisasedefinircomoelasinteragemumascomasoutras.

Entãooqueéumobjeto?Éumacoleçãodepropriedadeseações.Istopodeparecerestranho,masvamoslhedarumexemplo.

SequeremosmodelarumgatonóscriaremosumobjetoGatoquepossuialgumaspropriedades,porexemplocor,idade,humor(bom,mau,sonolento;)),dono(queéumobjetodaclassePessoaou,casosejaumgatoderua,essapropriedadeévazia).

EentãooGatotemalgumasações:ronronar,arranharoucomer(noqualvamosdaraogatoalgumaComidaDeGato,quepoderiaserumobjetoseparadocompropriedades,comosabor).

Gato

--------

cor

idade

humor

dono

ronronar()

arranhar()

comer(comida_de_gato)

ComidaDeGato

--------

sabor

Então,basicamente,aideiaédescrevercoisasreaisnocódigocompropriedades(chamadasdepropriedadesdoobjeto)eações(chamadasdemétodos).

DjangoGirlsTutorial

53ModelosdoDjango

Page 54: Djangogirls Tutorial Pt

Comonósiremosmodelaraspostagensdoblogentão?Queremosconstruirumblog,certo?

Precisamosresponderàpergunta:oqueéumapostagemdeblog?Quepropriedadesdeveter?

Bem,comcertezanossoblogprecisadealgumapostagemcomoseuconteúdoeumtítulo,certo?Tambémseriabomsaberquemaescreveu-entãoprecisamosdeumautor.Finalmente,queremossaberquandoapostagemfoicriadaepublicada.

Post

--------

title

text

author

created_date

published_date

Quetipodecoisapodeserfeitacomumapostagem?Serialegalteralgummétodoquepubliqueapostagem,nãoémesmo?

Entãoprecisamosdeummétodochamadopublicar.

Comojásabemosoquequeremosalcançar,podemoscomeçaramodelagememDjango!

ModelodoDjangoSabendooqueumobjetoé,nóscriaremosummodelonoDjangoparaapostagemdoblog.

UmmodelonoDjangoéumtipoespecialdeobjeto-eleésalvoemumbancodedados.Umbancodedadoséumacoleçãodedados.Obancodedadoséumlocalemquevocêvaisalvardadossobreusuários,suaspostagens,etc.UsaremosumbancodedadoschamadoSQLiteparaarmazenarasnossasinformações.EsteéoadaptadordebancodedadospadrãoDjango--elevaiserosuficienteparanósnestemomento.

Vocêpodepensaremummodelodebancodedadoscomoumaplanilhacomcolunas(campos)elinhas(dados).

Criandoumaaplicação

Paramantertudoarrumadovamoscriarumaplicativoseparadodentrodonossoprojeto.Émuitobomtertudoorganizadodesdeoinício.Paracriarumaplicativoprecisamosexecutaroseguintecomandonoconsole(apartirdodiretóriodjangogirlsondeestáoarquivomanage.py):

DjangoGirlsTutorial

54ModelosdoDjango

Page 55: Djangogirls Tutorial Pt

(myvenv)~/djangogirls$pythonmanage.pystartappblog

Vocêvainotarqueumnovodiretórioblogécriadoequeeleagoracontémumnúmerodearquivos.Nossosdiretóriosearquivosnonossoprojetodevemseparecercomeste:

djangogirls

├──mysite

|__init__.py

|settings.py

|urls.py

|wsgi.py

├──manage.py

└──blog

├──migrations

|__init__.py

├──__init__.py

├──admin.py

├──models.py

├──tests.py

└──views.py

DepoisdecriarumaplicativotambémprecisamosdizeraoDjangoquedeveusá-lo.Fazemosissonoarquivomysite/settings.py.PrecisamosencontraroINSTALLED_APPSeadicionarumalinhacom'blog',logoacimado).Éassimqueoprodutofinaldeveficarassim:

INSTALLED_APPS=(

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

'blog',

)

CriandoomodeloPostdonossoblog

Noarquivoblog/models.pydefinimostodososobjetoschamadosModelos-esteéumlugaremquevamosdefinirnossapostagemdoblog.

Vamosabrirblog/models.py,removatudodeleeescrevaocódigocomoeste:

DjangoGirlsTutorial

55ModelosdoDjango

Page 56: Djangogirls Tutorial Pt

fromdjango.dbimportmodels

fromdjango.utilsimporttimezone

classPost(models.Model):

author=models.ForeignKey('auth.User')

title=models.CharField(max_length=200)

text=models.TextField()

created_date=models.DateTimeField(

default=timezone.now)

published_date=models.DateTimeField(

blank=True,null=True)

defpublish(self):

self.published_date=timezone.now()

self.save()

def__str__(self):

returnself.title

Certifique-sedeterusadodoiscaracteres(_)emcadaladodostr.AquelescaracteressãousadosfreqüentementeemPythoneàsvezesoschamamosde"dunder"(abreviaçãode"double-underscore"ou"duplosublinhado").

Éassustador,não?Masnãosepreocupe,vamosexplicaroqueestaslinhassignificam!

Todasaslinhascomeçandocomfromouimportsãolinhasqueadicionamalgunspedaçosdeoutrosarquivos.Entãoaoinvésdecopiarecolarasmesmascoisasemcadaarquivo,podemosincluiralgumaspartescomfrom...import....

classPost(models.Model):-estalinhadefineonossomodelo(éumobjeto).

classéumapalavra-chaveespecialqueindicaqueestamosdefinindoumobjeto.Postéonomedonossomodelo,podemoslhedarumnomediferente(maséprecisoevitarosespaçosembrancoecaracteresespeciais).Semprecomeceumnomedeclassecomumaletramaiúscula.models.ModelsignificaqueoPostéummodelodeDjango,entãooDjangosabeelequedevesersalvonobancodedados.

Agorapodemosdefiniraspropriedadesquediscutimos:titulo,texto,data_criacao,data_publicacaoeautor.Paraissoprecisamosdefinirumtipodecampo(éumtexto?Éumnúmero?Umadata?Umarelaçãocomoutroobjeto,porexemplo,umusuário?).

models.CharField-assimécomovocêdefineumtextocomumnúmerolimitadodecaracteres.models.TextField-esteéparatextoslongossemumlimite.Seráidealparaumconteúdodepostdeblog,certo?models.DateTimeField-esteéumadataehora.

DjangoGirlsTutorial

56ModelosdoDjango

Page 57: Djangogirls Tutorial Pt

models.ForeignKey-esteéumlinkparaoutromodelo.Nósnãovamosexplicarcadapedaçodecódigoaqui,poisissolevariamuitotempo.VocêdeveolharadocumentaçãodoDJangosevocêquisersabermaissobrecamposdoModelecomodefinircoisasalémdestasdescritasacima(https://docs.djangoproject.com/en/1.8/ref/models/fields/#field-types).

Quetaldefpublish(self):?Éexatamenteonossométododepublishquefalávamosantes.def,significaquesetratadeumfunção/método.publishéonomedométodo.Vocêpodealterar,sequiser.Aregraéqueusamosletrasminúsculasesublinhadosemvezdeespaçosembranco(ouseja,sevocêquerterummétodoquecalculaopreçomédio,vocêpoderiachamá-localculate_average_price).

Métodosmuitasvezesreturnalgo.Háumexemplodeque,nométodo__str__.Nessecenário,quandochamamos__str__()teremosumtexto(string),comumtítulodoPost.

Sealgoaindanãoestáclarosobremodelos,sinta-selivreparapediroseutreinador!Sabemosqueémuitocomplicado,especialmentequandovocêaprenderoquesãoobjetosefunçõesaomesmotempo.Masesperoqueelesepareceumpoucomenosmágicaparavocêagora!

Criandotabelasparanossosmodelosnobancodedados

Oúltimopassoéadicionarnossonovomodeloparanossobancodedados.PrimeirotemosquefazeroDjangosaberquenóstemosalgumasmudançasemnossomodelo(sócriamosisso),digitepythonmanage.pymakemigrationsblog.Seráalgoparecidocomisto:

(myvenv)~/djangogirls$pythonmanage.pymakemigrationsblog

Migrationsfor'blog':

0001_initial.py:

-CreatemodelPost

Djangopreparaumarquivodemigraçãoquetemosdeaplicaragoraparanossobancodedados,tipopythonmanage.pymigrateblog,asaídadeveser:

(myvenv)~/djangogirls$pythonmanage.pymigrateblog

Operationstoperform:

Applyallmigrations:blog

Runningmigrations:

Applyingblog.0001_initial...OK

Viva!NossomodelodePostestáagoraemnossobancodedados,seriaumprazervê-lo,certo?SaltarparaopróximocapítuloparaveroaspectodoseuPost!

DjangoGirlsTutorial

57ModelosdoDjango

Page 58: Djangogirls Tutorial Pt

AdministraçãoParaadicionar,editareremoverpostagensquenóscriamosusaremosoDjangoadmin.

Vamosabriroarquivoblog/admin.pyesubstituirseuconteúdopor:

fromdjango.contribimportadmin

from.modelsimportPost

admin.site.register(Post)

Comovocêpodever,nósimportamos(incluímos)omodeloPostdefinidonocapítuloanterior.Paratornarnossomodelovisívelnapáginadeadministração,nósprecisamosregistrá-locom:admin.site.register(Post).

OK,horadeolharparaonossomodelodePost.Lembre-sedeexecutarpythonmanage.pyrunservernoconsoleparaexecutaroservidorweb.Váparaonavegadoredigiteoendereçohttp://127.0.0.1:8000/admin/Vocêveráumapáginadeloginassim:

Parafazerloginvocêprecisacriarumsuperuser-umusuárioquepossuicontrolesobretudodosite.Volteparaoterminaledigitepythonmanage.pycreatesuperuser,pressioneenteredigiteseunomedeusuário(caixabaixa,semespaço),endereçodee-maile

DjangoGirlsTutorial

58Administração

Page 59: Djangogirls Tutorial Pt

passwordquandoelesforemrequisitados.Nãosepreocupequevocênãopodeverasenhaquevocêestádigitando-éassimquedeveser.Sódigitá-laepressione'Enter'paracontinuar.Asaídadeveparecercomessa(ondeUsernameeEmaildevemserosseus):

(myvenv)~/djangogirls$pythonmanage.pycreatesuperuser

Username:admin

Emailaddress:[email protected]

Password:

Password(again):

Superusercreatedsuccessfully.

Volteparaaonavegadorefaçalogincomascredenciaisdesuperuserquevocêescolheu,vocêdevevisualizaropaineldecontroledoDjangoadmin.

Váparaaspostagenseexperimenteumpoucocomelas.Adicionecincoouseispostagens.Nãosepreocupecomoconteúdo-vocêpodecopiarecolaralgumtextodestetutorialparaoconteúdoparaeconomizartempo:).

Certifique-sequepelomenosduasoutrêspostagens(masnãotodas)têmadatadepublicaçãodefinida.Issoseráútildepois.

DjangoGirlsTutorial

59Administração

Page 60: Djangogirls Tutorial Pt

SevocêquisersabermaissobreoDjangoadmin,vocêdeveconferiradocumentaçãodoDjango:https://docs.djangoproject.com/en/1.8/ref/contrib/admin/

Esteéprovavelmenteumbommomentoparatomarumcafé(ouchocolate)oualgoparacomerparareporaasenergias.VocêcriouseuprimeiromodelodeDjango-vocêmereceumpoucodedescanso!

DjangoGirlsTutorial

60Administração

Page 61: Djangogirls Tutorial Pt

Implantação!NotaOcapítuloseguintepodeseràsvezesumpoucodifícildepassar.Persistaetermine-o;Implantaçãoéumaparteimportantedoprocessodedesenvolvimentodewebsite.Estecapítuloestálocalizadonomeiodotutorialparaqueseututorpossalheajudarcomoprocessoligeiramentecomplexodecolocarseusiteonline.Istosignificaquevocêaindapodeterminarotutorialporcontaprópriasevocêcontinuaremoutromomento.

Atéagoranossositesóestavadisponívelnoseucomputador,agoravocêvaiaprendercomopublicarelenainternet!AimplantaçãoéoprocessodepublicaçãodoseuaplicativonaInternetdetalformaqueaspessoaspossam,finalmente,verseuaplicativo:).

Comovocêaprendeu,umwebsiteprecisaestarlocalizadonumservidor.Existemmuitosprovedores,masiremosutilizaroquetemumprocessodedeployrelativamentesimples:PythonAnywhere.PythonAnywhereégratuitoparaaplicaçõespequenasquenãopossuemmuitosvisitantes,entãoserásuficienteparavocêporenquanto.

OoutroserviçoexternoqueusaremoséGitHub,queéumserviçodehospedagemdecódigo.Existemoutros,masquasetodososprogramadorespossuemumacontanoGitHubatualmenteeagoravocêtambém!

UsaremosoGitHubcomoumtrampolimparatransportarnossocódigoparaoPythinAnywhere.

GitGité"sistemadecontroledeversão"usadopormuitosprogramadores-umsoftwarequecontrolamudançasnosarquivosaolongodotempoparaquevocêpossarecuperarversõesespecíficasdepois.Umpoucocomo"controlarmudanças"noMicrosoftWord,masmuitomaispoderoso.

InstalandooGit

Windows

DjangoGirlsTutorial

61Implantação!

Page 62: Djangogirls Tutorial Pt

VocêpodebaixarGitemgit-scm.com.Vocêpodeapertar"nextnextnext"emtodosospassosexcetoum;noquintopassochamado"AdjustingyourPATHenvironment",escolha"RunGitandassociatedUnixtoolsfromtheWindowscommand-line"(aopçãodebaixo).Alémdisso,opadrãoestáótimo.CheckoutestiloWindows,commitUnix-stylelinhasdeconfirmaçãoestábom.

MacOS

BaixarGitgit-scm.comesigaasinstruções.

Linux

Seelejánãoestiverinstalado,Gitdeveestardisponívelatravésdeseugerenciadordepacotes,entãotente:

sudoapt-getinstallgit

#or

sudoyuminstallgit

ComeçandonossorepositórionoGitGitcontrolaasalteraçõesparaumdeterminadoconjuntodearquivosnoquechamamosderepositóriodecódigo(ou"repo").Vamoscomeçarumparanossoprojeto.Abraoconsoleeexecuteessescomandos,nodiretóriodjangogirls:

Nota:Verifiqueoseudiretóriodetrabalhoatualcomumpwd(OSX/Linux)ouocomandocd(Windows)antesdeinicializarorepositório.Vocêdeveestarnapastadjangogirls.

$gitinit

InitializedemptyGitrepositoryin~/djangogirls/.git/

$gitconfiguser.name"YourName"

[email protected]

Inicializarorepositóriogitéalgoquesóprecisamosfazerumavezporprojeto(evocênãoteráquere-introduzironomedeusuárioee-mailnuncamais)

Gitirácontrolarasalteraçõesparatodososarquivosepastasnestediretório,masexistemalgunsarquivosquequeremosignorar.Fazemosissoatravésdacriaçãodeumarquivochamado.gitignorenodiretóriobase.Abraseueditorecrieumnovoarquivocomoseguinteconteúdo:

DjangoGirlsTutorial

62Implantação!

Page 63: Djangogirls Tutorial Pt

*.pyc

__pycache__

myvenv

db.sqlite3

.DS_Store

Esalvecomo.gitignorenapastadenívelsuperior"djangogirls".

Nota:Opontonoiníciodonomedoarquivoéimportante!Sevocêestátendoalgumadificuldadeemcriá-la(MacsnãogostamdecriararquivosquecomeçamcomumpontoatravésdoFinder,porexemplo),useorecurso"SaveAs"noseueditorquesemprefunciona.

Éumaboaidéiaparausarumcomandodegitstatusantesdegittaddousemprequevocênãotivercertezadequeseráfeito,paraevitarsurpresas(porexemplo,serãoadicionadosarquivoserradosoucommitados).Ocomandogitstatusretornainformaçõessobretodososarquivoscontrolado/modificado/encenado,statusderamoemuitomais.Ooutputdevesersemelhantea:

$gitstatus

Onbranchmaster

Initialcommit

Untrackedfiles:

(use"gitadd<file>..."toincludeinwhatwillbecommitted)

.gitignore

blog/

manage.py

mysite/

nothingaddedtocommitbutuntrackedfilespresent(use"gitadd"totrack)

Efinalmentenóssalvamosnossasalterações,Váparaoseuconsoleeexecuteestescomandos:

$gitadd-A.

$gitcommit-m"MyDjangoGirlsapp,firstcommit"

[...]

13fileschanged,200insertions(+)

createmode100644.gitignore

[...]

createmode100644mysite/wsgi.py

DjangoGirlsTutorial

63Implantação!

Page 64: Djangogirls Tutorial Pt

EmpurrandoonossocódigoparaGitHubVáparaGitHub.comecadastreumanovaegratuitacontadeusuário.Emseguida,crieumnovorepositório,edêonome"my-first-blog".Deixeo"initialisewithaREADME"desmarcado,deixeaopção.gitignoreembranco(jáfizemosissomanualmente)ealicençacomoNone.

NotaOnomemy-first-blogéimportante--vocêpoderiaescolheroutracoisa,masvamosusá-lomuitasvezesnasinstruçõesabaixoevocêteriaquesubstituí-locadavez.Éprovavelmentemaisfácilficarcomonomemy-first-blog.

Natelaseguinte,vocêserámostradaacloneURLdoseurepo.Escolhaaversão"HTTPS",copie,evamoscolá-lonoterminalembreve:

DjangoGirlsTutorial

64Implantação!

Page 65: Djangogirls Tutorial Pt

AgoraprecisamosligarorepositórioGitnoseucomputadorcomonoGitHub.

$gitremoteaddoriginhttps://github.com/<your-github-username>/my-first-blog.git

$gitpush-uoriginmaster

DigiteseuGitHubusernameesenha,evocêdeveveralgocomoisto:

Usernamefor'https://github.com':hjwp

Passwordfor'https://[email protected]':

Countingobjects:6,done.

Writingobjects:100%(6/6),200bytes|0bytes/s,done.

Total3(delta0),reused0(delta0)

Tohttps://github.com/hjwp/my-first-blog.git

*[newbranch]master->master

Branchmastersetuptotrackremotebranchmasterfromorigin.

SeucódigoagoraestánoGitHub.Váeconfira!Vocêsaberáqueestáemboacompanhia-Django,oDjangoGirlsTutorialemuitosoutrosgrandesprojetosdesoftwaredefonteabertatambémhospedamseucódigonoGitHub:)

CriaçãodenossoblogemPythonAnywhereEmseguida,éhoradeseinscreverparaumacontagratuitade"Beginner"naPythonAnywhere.

DjangoGirlsTutorial

65Implantação!

Page 66: Djangogirls Tutorial Pt

www.pythonanywhere.comNota:aoescolherseunomedeutilizadoraqui,tenhaemmentequeaURLdoseublogteráoformulárioyourusername.pythonanywhere.com,entãoescolhaseunicknameouonomedoqueéoblog.

PullingourcodedownonPythonAnywhereQuandovocêseinscreveparaPythonAnywhere,vocêélevadoaoseupaineldecontroleoupágina"Consoles".Escolhaaopçãoiniciaroconsole"Bash"--queéaversãoPythonAnywheredeumconsole,comoaquelanoseuPC

Nota:PythonAnywhereébaseadoemLinux,assimsevocêestivernoWindowsoconsolevaiparecerumpoucodiferentedoqueestánoseucomputador.

VamospuxarnossocódigodeGitHubemPythonAnywhereatravésdacriaçãodeum"clone"dorepo.DigiteoseguinteparaoconsolenaPythonAnywhere:

$gitclonehttps://github.com/<your-github-username>/my-first-blog.git

IstopuxaráumacópiadoseucódigoparaPythonAnywhere.Confiradigitando:

$treemy-first-blog

my-first-blog/

├──blog

│├──__init__.py

│├──admin.py

│├──migrations

││├──0001_initial.py

││└──__init__.py

│├──models.py

│├──tests.py

│└──views.py

├──manage.py

└──mysite

├──__init__.py

├──settings.py

├──urls.py

└──wsgi.py

CriandoumvirtualenvnaPythonAnywhere

Assimcomofezemseuprópriocomputador,vocêpodecriarumvirtualenvnaPythonAnywhere.NoconsoleBash,digite:

DjangoGirlsTutorial

66Implantação!

Page 67: Djangogirls Tutorial Pt

20:20~$cdmy-first-blog

20:20~$virtualenv--python=python3.4myvenv

Runningvirtualenvwithinterpreter/usr/bin/python3.4

[...]

Installingsetuptools,pip...done.

20:20~$sourcemyvenv/bin/activate

(mvenv)20:20~$pipinstalldjangowhitenoise

Collectingdjango

[...]

Successfullyinstalleddjango-1.8.5whitenoise-2.0

Coletadearquivosestáticos.

Vocêestavaimaginandooqueé"whitenoise"?Éumaferramentaparaserviroschamados"arquivosestáticos".Arquivosestáticosfuncionamdeformadiferentenosservidoresemcomparaçãocomnossoprópriocomputador,eprecisamosdeumaferramentacomoo"whitenoise"paraatendê-los.

Vamosdescobrirumpoucomaissobrearquivosestáticosmaistardenotutorial,quandovamoseditaroCSSparaonossosite.

Porenauntosóprecisamosexecutarumcomandoextrachamado"collectstatic"noservidor.IssodizproDjangoreunirtodososarquivosestáticosqueeleprecisanoservidor.Emsuamaioria,estessãoosarquivosestáticosquefazemositedoadminbonitonomomento.

20:20~$pythonmanage.pycollectstatic

Youhaverequestedtocollectstaticfilesatthedestination

locationasspecifiedinyoursettings:

/home/edith/my-first-blog/static

Thiswilloverwriteexistingfiles!

Areyousureyouwanttodothis?

Type'yes'tocontinue,or'no'tocancel:yes

Digite"Sim"evaiembora!Vocênãoadorafazercomputadoresimprimirpáginasepáginasdetexto?Semprefaçopequenosruídosparaacompanhá-lo.Brp,brpbrp...

DjangoGirlsTutorial

67Implantação!

Page 68: Djangogirls Tutorial Pt

opying'/home/edith/.virtualenvs/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/js/actions.min.js'

Copying'/home/edith/.virtualenvs/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/js/inlines.min.js'

[...]

Copying'/home/edith/.virtualenvs/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/css/changelists.css'

Copying'/home/edith/.virtualenvs/mvenv/lib/python3.4/site-packages/django/contrib/admin/static/admin/css/base.css'

62staticfilescopiedto'/home/edith/my-first-blog/static'.

CriandoobancodedadosemPythonAnywhere

Aquiestáoutracoisaqueédiferenteentreseucomputadoreoservidor--eleusaumbancodedadosdiferente.Entãoascontasdeusuárioemensagenspodemserdiferentesnoservidorenoseucomputador.

Entãonósvamosinicializarobancodedadosnoservidortalcomofizemosnoseuprópriocomputador,commigrateecreatesuperuser:

(mvenv)20:20~$pythonmanage.pymigrate

Operationstoperform:

[...]

Applyingsessions.0001_initial...OK

(mvenv)20:20~$pythonmanage.pycreatesuperuser

PublicaçãodonossoblogcomoumaplicativowebAgoranossocódigoestánaPythonAnywhere,nossavirtualenvestápronta,osarquivosestáticosestãorecolhidoseobancodedadosestáinicializado,estamosprontosparapublicá-locomoumaplicativodaweb.

CliqueemvoltarparaoPythonAnywheredashboardclicandonoseulogotipoecliquenaguiaWebeváemAddanewwebapp.

Nacaixadediálogo,apósaconfirmaçãodeseunomededomínio,escolhamanualconfiguration(NBnãoaopção"Django").Emseguida,escolhaPython3.4ecliqueemNextparaconcluiroassistente.

Notacertifique-sevocêescolheuaopção"Manualconfiguration",nãoa"Django".NóssomosdemaisparaopadrãodeconfiguraçãoDjangodaPythonAnywhere;-)

Definindoovirtualenv

DjangoGirlsTutorial

68Implantação!

Page 69: Djangogirls Tutorial Pt

VocêserálevadoparaateladeconfiguraçãodePythonAnywhereparaseuwebappqueéondevocêprecisarádeirquandoquiserfazeralteraçõesparaoaplicativonoservidor.

Naseção"Virtualenv",cliquenotextovermelhoquediz"Enterthepathtoavirtualenv"edigite:/home//my-first-blog/myvenv/

Nota:substituaseupróprionomedeusuárioconformeapropriado.Sevocêcometerumerro,PythonAnywhereirámostrarumpequenoaviso.

ConfigurandooarquivoWSGI

DjangofuncionausandooWSGIprotocol,umpadrãoparaservirsitesusandoPython,queoferecesuporteaPythonAnywhere.AmaneiraqueconfiguramosPythonAnywhereparareconhecernossoblogDjangoéeditandoumarquivodeconfiguraçãodoWSGI.

Cliquenolink"AWSGIconfigurationfile"(naseção"Code"pertodotopodapágina--elevaisernomeadoalgocomo/var/www/<your-username>_pythonanywhere_com_wsgi.py),evocêserálevadoparaumeditor.

Excluatodooconteúdoatualesubstituacomalgoparecidocomisto:

DjangoGirlsTutorial

69Implantação!

Page 70: Djangogirls Tutorial Pt

importos

importsys

path='/home/<your-username>/my-first-blog'#useyourownusernamehere

ifpathnotinsys.path:

sys.path.append(path)

os.environ['DJANGO_SETTINGS_MODULE']='mysite.settings'

fromdjango.core.wsgiimportget_wsgi_application

fromwhitenoise.djangoimportDjangoWhiteNoise

application=DjangoWhiteNoise(get_wsgi_application())

Notanãoseesqueçadesubstituiremseupróprionomedeusuárioondediz<your-username>

OqueessearquivofazédizerPythonAnywhereondemoraanossaaplicaçãowebequalonomedoarquivodeconfiguraçõesDjango.Eletambémdefineaferramentadearquivosestáticos"whitenoise".

AperteSaveeentãovolteparaaguiaWeb.

Játerminamos!AperteobotãograndeverdedeReloadevocêserácapazdeirverosseuaplicativo.Vocêencontraráumlinkparaelenotopodapágina.

DicasdedebuggingSevocêvirumerroquandovocêtentavisitaroseusite,oprimeirolugarparaprocuraralgumainformaçãodedebuggingénoseuerrorlog--vocêencontraráumlinkparaissonaguiawebPythonAnywhere.Versehámensagensdeerrolá.Asmaisrecentesestãonaparteinferior.Problemascomunsincluem

esquecerumdospassosquefizemosnoconsole:criandoovirtualenv,ativá-lo,instalandooDjango,collectstatic,inicializandoobancodedadoscometerumerronocaminhodovirtualenvnaguiaweb--haverágeralmenteumapequenamensagemdeerrovermelholá,seháumproblemacometerumerronoarquivodeconfiguraçãoWSGI..--vocêusouocaminhoparaapastadomy-first-blogcertinho?

Otreinadorestáaquiparaajudar!

Vocêestálive!

DjangoGirlsTutorial

70Implantação!

Page 71: Djangogirls Tutorial Pt

Apáginapadrãoparaseusitedevedizer"Bem-vindoaoDjango",comoacontecenoseuPClocal.Tenteadicionar/admin/paraofinaldaURL,evocêserálevadoaositeadmin.Fazerlogincomonomedeusuárioesenha,evocêveráquevocêpodeadicionarnovasmensagensnoservidor.

Dëemvocêmesmaumenormetapinhanascostas-implantaçõesdeservidorsãoumadaspartesmaisdifíceisdodesenvolvimentoweb,emuitasvezeslevaaspessoasváriosdiasantesdefazerfuncionar.Masvocêtemseusitepublicado,nainternet,assim!

DjangoGirlsTutorial

71Implantação!

Page 72: Djangogirls Tutorial Pt

UrlsEstamosprestesaconstruirnossaprimeiraWebpage-umapáginainicialparaoseublog!Masprimeiro,vamosaprenderumpoucomaissobreDjangourls.

OqueéumaURL?UmaURLésimplesmenteumendereçodaweb,vocêpodeverumaURLtodavezquevocêvisitaqualquersite-évisívelnabarradeendereçosdoseunavegador(Sim!127.0.0.1:8000éumaURL!Ehttp://djangogirls.comtambéméumaURL):

CadapáginanaInternetprecisadesuaprópriaURL.DestaformaseuaplicativosabeoquedevemostraraumusuárioqueabreumaURL.EmDjango,nósusamosalgochamadoURLconf(configuraçãodeURL),queéumconjuntodepadrõesqueDjangovaitentarcoincidircomaURLrecebidaparaencontraravisãocorreta.

ComofuncionamasURLsemDjango?Vamosabriroarquivomysite/urls.pyevercomqueeleseparece:

fromdjango.conf.urlsimportinclude,url

fromdjango.contribimportadmin

urlpatterns=[

#Examples:

#url(r'^$','mysite.views.home',name='home'),

#url(r'^blog/',include('blog.urls')),

url(r'^admin/',include(admin.site.urls)),

]

Comovocêpodever,oDjangojácolocoualgumacoisalápranós.

DjangoGirlsTutorial

72Urls

Page 73: Djangogirls Tutorial Pt

Aslinhasquecomeçamcom#sãocomentários-issosignificaqueessaslinhasnãoserãoexecutadaspeloPython.Muitoútil,não?

AURLdoadmin,quevocêvisitounocapítuloanteriorjáestáaqui:

url(r'^admin/',include(admin.site.urls)),

IssosignificaqueparacadaURLquecomeçacomadmin/oDjangoiráencontrarumcorrespondentemododeexibição.NestecasonósestamosincluindoummontedeadminURLsparaqueissonãofiquetudoembaladonestepequenoarquivo..--émaislegívelemaislimpo.

RegexVocêquersabercomooDjangocoincidecomURLsparaviews?Bem,estaparteécomplicada.oDjangousaoregex--expressõesregulares.Regextemmuito(muito!)denormasqueformamumpadrãodepesquisa.Comoregexessãoumtópicoavançado,nósveremosemdetalhescomoelasfuncionam.

Sevocêaindaquiserentendercomocriamosospadrões,aquiestáumexemplodoprocesso-sóprecisamosumsubconjuntolimitadoderegrasparaexpressaropadrãoqueprocuramos,ouseja:

^paraoiníciodotexto

$paraofinaldotexto

\dparaumdígito

+paraindicarqueoitemanteriordeveserrepetidopelomenosumavez

()paracapturarpartedopadrão

Qualqueroutracoisanadefiniçãodeurlserálevadaliteralmente.

Agoraimaginequevocêtemumsitecomoendereçoassim:http://www.mysite.com/post/12345/,onde12345éonúmerodoseupost.

Escreverviewsseparadasparatodososnúmerosdepostseriamuitochato.Comexpressõesregularespodemoscriarumpadrãoqueirácoincidircomaurleextraironúmeroparanós: post/(\d+)/$.Vamosaospoucosveroqueestamosfazendoaqui:

^post/estádizendoaoDjangoparapegartudoquetenhapost/noiníciodaurl(logoapóso )(\d+)significaquehaveráumnúmero(umoumaisdígitos)equequeremosonúmerocapturadoeextraído/dizparaoDjangoquedeveseguiroutro/

DjangoGirlsTutorial

73Urls

Page 74: Djangogirls Tutorial Pt

$indicaofinaldaURLsignificandoqueapenassequênciasterminandocomo/irãocorresponderaessepadrão

SuaprimeiraurlDjango!ÉhoradecriarnossaprimeiraURL!Queremoshttp://127.0.0.1:8000/paraserumapáginainicialdonossoblogeexibirumalistadeposts.

Tambémqueremosmanteroarquivodemysite/urls.pylimpo,aínósimportaremosurlsdanossaaplicaçãoblogparaoarquivoprincipalmysite/urls.py.

Váemfrente,apagueaslinhascomentadas(aslinhasquecomeçamcom#)eadicioneumalinhaquevaiimportarblog.urlsparaaurlprincipal('').

Oseuarquivomysite/urls.pydeveagoraseparecercomisto:

fromdjango.conf.urlsimportinclude,url

fromdjango.contribimportadmin

urlpatterns=[

url(r'^admin/',include(admin.site.urls)),

url(r'',include('blog.urls')),

]

ODjangoagorairáredirecionartudooqueentraem'http://127.0.0.1:8000/'parablog.urlseprocurarpornovasinstruçõeslá.

AoescreverasexpressõesregularesemPythonésemprefeitocomrnafrentedasequência-issoésóumadicaútilparaPythonqueaseqüênciapodecontercaracteresespeciaisquenãosãodestinadasparaPythonemsi,masemvezdissosãopartedaexpressãoregular.

blog.urlsCrieumnovoarquivovazioblog/urls.py.Tudobem!Adicioneestasduasprimeiraslinhas:

fromdjango.conf.urlsimportinclude,url

from.importviews

AquinósestamosapenasimportandométodosdoDjangoetodososnossosviewsdoaplicativoblog(aindanãotemosnenhuma,masteremosemumminuto!)

DepoisdissonóspodemosadicionarnossoprimeiraURLpadrão:

DjangoGirlsTutorial

74Urls

Page 75: Djangogirls Tutorial Pt

urlpatterns=[

url(r'^$',views.post_list),

]

Comovocêpodever,estamosagoraatribuindoumaviewchamadapost_listpara $

URL.Essaexpressãoregularcorresponderáa (umcomeço)seguidopor$(fim)-entãosomenteumaseqüênciavaziairácorresponder.Eissoécorreto,porqueemresolvedoresdeDjangourl,'http://127.0.0.1:8000/'nãoéumapartedaURL.EstepadrãoirámostraroDjangoqueviews.post_listéolugarcertoparair,sealguémentraemseusitenoendereço'http://127.0.0.1:8000/'.

Tudocerto?Abrahttp://127.0.0.1:8000noseunavegadorpraveroresultado.

Nãotemmais"ItWorks!'maisein?Nãosepreocupe,ésóumapáginadeerro,nadaatemer!Elassãonaverdademuitoúteis:

Vocêpodelerquenãohánoattribute'post_list'.Opost_listtelembraalgumacoisa?Istoécomochamamosonossoview!Issosignificaqueestátudonolugar,sónãocriamosnossaviewainda.Nãosepreocupe,nóschegaremoslá.

SevocêquersabermaissobreDjangoURLconfs,vejaadocumentaçãooficial:https://docs.djangoproject.com/en/1.8/topics/http/urls/

DjangoGirlsTutorial

75Urls

Page 76: Djangogirls Tutorial Pt

Views-horadecriar!Éhoraderesolverobugquecriamosnocapítuloanterior:)

Umaviewécolocadaondenóscolocamosa"lógica"danossaaplicação.Eleirásolicitarinformaçõesapartirdomodelquevocêcriouantesepassá-loparaumtemplatequevocêvaicriarnopróximocapítulo.Views,nofundo,nãopassamdemétodosescritosemPythonquesãoumpoucomaiscomplicadosdoqueaquiloquefizemosnocapítuloIntroduçãoaoPython.

Asviewssãopostasnoarquivoviews.py.Nósvamosadicionarnossasviewsnoarquivoblog/views.py.

blog/views.pyOK,vamosabriroarquivoeveroquetemnele:

fromdjango.shortcutsimportrender

#Createyourviewshere.

Nãotemmuitacoisa.Aviewmaisbásicaseparececomisto.

defpost_list(request):

returnrender(request,'blog/post_list.html',{})

Comovocêpodever,nóscriamosummétodo(def)chamadopost_listqueaceitaopedidoeretornarummétodorenderseráprocessado(paramontar)nossomodeloblog/post_list.html.

Salveoarquivo,váparahttp://127.0.0.1:8000/evejaoquetemosagora.

Outroerro!Leiaoqueestáacontecendoagora:

DjangoGirlsTutorial

76Views-horadecriar!

Page 77: Djangogirls Tutorial Pt

Estaéfácil:TemplateDoesNotExist.Vamoscorrigirestebugecriarummodelonopróximocapítulo!

AprendamaissobreasviewsdoDjangolendoadocumentaçãooficial:https://docs.djangoproject.com/en/1.8/topics/http/views/

DjangoGirlsTutorial

77Views-horadecriar!

Page 78: Djangogirls Tutorial Pt

IntroduçãoaHTMLVocêpodeseperguntar:eoqueéumtemplate?

Umtemplateéumarquivoquenóspodemosreutilizarparaapresentardiferentesinformaçõesdeumaformaconsistente.Porexemplo,vocêpoderiausarumtemplateparateajudaraescreverumacarta,pois,emboracadacartapossuaumamensagemeumdestinodiferente,todasterãosempreomesmoformato.

OformatodotemplatedoDjangoédescritoemumalinguagemchamadaHTML(esseéomesmHTMLquemencionamosnoprimeirocapítuloComoaInternetfunciona).

OqueéHTML?HTMLéumsimplescódigoqueéinterpretadopeloseunavegadorweb-comooChrome,oFirefoxouoSafari-paraexibirumapáginadawebparaousuário.

HTMLsignifica"HyperTextMarkupLanguage".HiperTextsignificaqueéumtipodetextoquesuportahiperlinksentrepáginas.Marcaçãonadamaiséquemarcarumdocumentocomcódigosquedizemparaalguém(nessecaso,onavegadorweb)comoapáginadeveráserinterpretada.CódigoemHTMLéfeitocomtags,cadaumacomeçandocom<eterminandocom>.Essastagsmarcamoselementos.

Seuprimeirotemplate!Criarumtemplatesignificacriarumarquivodetemplate.Tudoéumarquivo,certo?Provavelmentevocêjádeveternotadoisso.

Ostemplatessãosalvosnodiretórioblog/templates.Logo,crieumdiretóriochamadotemplatesdentrododiretóriodoseublog.Emseguida,crieoutrodiretóriochamadoblogdentrodadiretóriotemplates:

blog

└───templates

└───blog

(Vocêdeveestarseperguntandoporquenósprecisamosdedoisdiretórioschamadosblog-comovocêdescobrirámaisparafrente,essaéumasimpleseútilconvençãoquefacilitaavidaquandoascoisascomeçaremaficarmaiscomplicadas.)

DjangoGirlsTutorial

78IntroduçãoaHTML

Page 79: Djangogirls Tutorial Pt

Eagoranóscriamosoarquivopost_list.html(deixe-oembrancoporagora)dentrododiretórioblog/templates/blog.

Vejacomoonossositeestáseparecendoagora:http://127.0.0.1:8000/

SeocorrerumerrodeTemplateDoesNotExiststentereiniciaroseuservidor.Entrenalinhadecomando,pareoservidorpressionandoCtrl+C(ControlseguidodateclaC,juntas)ereinicie-orodandopythonmanage.pyrunserver.

Acabaram-seoserros!Parabéns:)Entretanto,nossositenãomostranadaanãoserumapáginaembranco.Issoporqueonossotemplateestávazio.Entãoprecisamosconsertarisso.

Adicioneaseguintelinhadentrodotemplate:

<html>

<p>Hithere!</p>

<p>Itworks!</p>

</html>

Comonossositesepareceagora?Cliqueparadescobrir:http://127.0.0.1:8000/

Funcionou!Bomtrabalho:)

Atagmaisbásica,<html>,estarásemprenocomeçodequalquerpáginadaweb,assimcomo,</html>sempreestaránofim.Comovocêpodever,todooconteúdode

DjangoGirlsTutorial

79IntroduçãoaHTML

Page 80: Djangogirls Tutorial Pt

umwebsiteseencontraentreatagdeinício<html>eentreatagdefim</html><p>éatagquedenominaparágrafos;</p>determinaofimdecadaparágrafo

Head&bodyCadapáginaHTMLtambémédivididaemdoiselementos:head(cabeça)ebody(corpo).

headéumelementoquecontéminformaçõessobreodocumentoquenãosãomostradasnatela.

bodyéumelementoquecontémtudooqueéexibidocomopartedeumapáginadeumsite.

Nósusamosatag<head>paradizeraonavegadorsobreasconfiguraçõesdapágina.Porsuavez,atag<body>dizaonavegadoroquehádeverdadenapágina.

Porexemplo,vocêpodeporoelementotítulodeumapáginawebdentrodatag<head>.Veja:

<html>

<head>

<title>Ola'sblog</title>

</head>

<body>

<p>Hithere!</p>

<p>Itworks!</p>

</body>

</html>

Salveoarquivoeatualizesuapágina.

Viucomoonavegadorentendeuque"Ola'sblog"éotítulodapágina?Eleinterpretou<title>Ola'sblog</title>ecolocouotextonabarradetítulodoseunavegador(etambémseráusadoparaosfavoritoseoutrascoisasmais).

DjangoGirlsTutorial

80IntroduçãoaHTML

Page 81: Djangogirls Tutorial Pt

Provavelmentevocêjádeveternotadoquecadatagdeaberturacasacomumatagdefechamento,comuma/,equeoselementosestãoaninhados(ex.:vocênãopodefecharumtagemparticularantesquetodasasoutrastagsqueestiveremdentrodelajáestejamfechadas).

Écomocolocarcoisasdentrodecaixas.Vocêtemumagrandecaixa,<html></html>;dentrodelahá<body></body>,sendoqueestaaindacontémcaixasmenors:<p></p>.

Vocêprecisaseguiressasregrasdefechamentodetags,edeaninhamentodeelementos-sevocênãofizerisso,onavegadorpoderánãoestaraptoparainterpretarseucódigodemaneiracorretaesuapáginaseráexibidademaneiraincorreta.

CustomizeseutemplateAgoravocêpodesedivertirumpoucotentandocustomizaroseutemplate!Aquiestãoalgumastagsúteisparaisso:

<h1>Umtítulo</h1>-paraotítulomaisimportante<h2>Umsub-título</h2>paraumtítuloumnívelabaixo<h3>Umsub-sub-título</h3>...eporaívai,até<h6><em>texto</em>enfatizaseutexto<strong>text</strong>enfatizafortementeseutexto<br/>pulaparaapróximalinha(vocênãopodecolocarnadadentrodebr)<ahref="http://djangogirls.org">link</a>criaumlink<ul><li>primeiroitem</li><li>segundoitem</li></ul>criaumalista,exatamentecomoessa!<div></div>defineumaseçãodapágina

Aquiestáumexemplodeumtemplatecompleto:

DjangoGirlsTutorial

81IntroduçãoaHTML

Page 82: Djangogirls Tutorial Pt

<html>

<head>

<title>DjangoGirlsblog</title>

</head>

<body>

<div>

<h1><ahref="">DjangoGirlsBlog</a></h1>

</div>

<div>

<p>published:14.06.2014,12:14</p>

<h2><ahref="">Myfirstpost</a></h2>

<p>Aeneaneuleoquam.Pellentesqueornaresemlaciniaquamvenenatisvestibulum.Donecidelitnonmiportagravidaategetmetus.Fuscedapibus,tellusaccursuscommodo,tortormauriscondimentumnibh,utfermentummassajustositametrisus.

</div>

<div>

<p>published:14.06.2014,12:14</p>

<h2><ahref="">Mysecondpost</a></h2>

<p>Aeneaneuleoquam.Pellentesqueornaresemlaciniaquamvenenatisvestibulum.Donecidelitnonmiportagravidaategetmetus.Fuscedapibus,tellusaccursuscommodo,tortormauriscondimentumnibh,utf.

</div>

</body>

</html>

Nóscriamostrêsseçõesdivaqui.

Oprimeiroelementodivpossuiotítulodonossoblog-éumtítuloeumlinkOsoutrosdoiselementosdivpossuemnossaspostagenscomadatadepublicação,h2comotítulodapostagemqueéclicáveledoisps(parágrafos)detexto,umparaadataeoutroparaotextodapostagem.

Issonosdáoseguinteefeito:

DjangoGirlsTutorial

82IntroduçãoaHTML

Page 83: Djangogirls Tutorial Pt

Yaaay!Mas,atéagora,nossotemplatemostraexatamantesempreamesmainformação-sendoque,anteriormente,nósfalávamossobretemplatescomoumamaneiraparaexibirinformaçõesdiferentesemummesmoformato.

OquenósrealmentequeremosfazeréexibirpostagensreaisqueforamadicionadasnoDjangoadmin-eissoéoquefaremosemseguida.

Maisumacoisa:deploy!SeriabomvertudoistonaInternet,certo?VamosfazeroutrodeployPythonAnywhere:

Commit,eponhaseucódigonoGitHub

Primeirodetudo,vejamosquaisarquivosforamalteradosdesdeaúltimaimplantação:

$gitstatus

Verifiquesevocêestánodiretóriodjangogirlsevamosdizeraogitparaincluirtodasasmudançasdentrodestediretório:

$gitadd-A.

DjangoGirlsTutorial

83IntroduçãoaHTML

Page 84: Djangogirls Tutorial Pt

Nota-A(abreviaçãode"all",tudoeminglês)significaqueogittambémreconhecerásevocêdeletoualgumarquivo(porpadrão,ogitapenasreconhecearquivoscriados/modificados).Lembre-setambém(docapítulo3)que.significaodiretórioatual.

Antesdenósfazermosouploaddetodososaqruivos,chequemosoqueogitenviará(todososarquivosqueogitforenviardeveráapareceemverde):

$gitstatus

Estamosquaselá!Agoraéhoradedizeraeleparasalvaressamodificaçãoemseuhistórico.Nósdaremosaeleuma"mensagemdecommit"ondenósdescrevemosasmodificaçõesquefizemos.Vocêpodeescreveroquevocêquiseragora,masserámaisútilsevocêescreveralgumacoisamaisdescritiva,algoparavocêpoderselembrardascoisasquevocêfezfuturamente.

$gitcommit-m"ChangedtheHTMLforthesite."

Certifique-sequevocêusouaspasduplasparadelimitaramensagemdocommit.

Quandofizermosisso,nósfazemosupload(envio)dasnossasmudançasparaoPythonAnywhere:

gitpush

BotedeunovocódigonoPythonAnywhereerecarregueoseuaplicativodaweb

AbraapáginadeconsolesdePythonAnywhereeváparaoseuconsoleBash(oucomeçarumnovo).Emseguida,execute:

$cd~/my-first-blog

$sourcemyvenv/bin/activate

(myvenv)$gitpull

[...]

(myvenv)$pythonmanage.pycollectstatic

[...]

Evejaseucódigosendobaixado.Sevocêdesejaverificarsejáchegou,podeirparaaFilestabeverseucódigonoPythonAnywhere.

Finalmente,puleparaaWebtabeaperteReloademseuaplicativoweb.

DjangoGirlsTutorial

84IntroduçãoaHTML

Page 85: Djangogirls Tutorial Pt

Suaatualizaçãodeveestarlive!Váemfrenteeatualizeseusitenonavegador.Asalteraçõesdevemservisíveis:)

DjangoGirlsTutorial

85IntroduçãoaHTML

Page 86: Djangogirls Tutorial Pt

QuerySetseORMdoDjangoNestecapítulovocêvaiaprendercomoDjangoseconectaaobancodedadosecomoelearmazenadados.Vamosnessa!

OqueéumQuerySet?UmQuerySet(conjuntodepesquisa),nofundo,éumalistadeobjetosdeumdadomodelo.UmQuerySetpermitequevocêleiaosdadosdobanco,filtreeordeneomesmo.

Émaisfácilaprenderporexemplos.Vamostentar?

OShelldoDjangoAbraoterminaledigite:

(myvenv)~/djangogirls$pythonmanage.pyshell

Oresultadodeveser:

(InteractiveConsole)

>>>

AgoravocêestánoconsoleinterativodoDjango.EleécomoopromptdoPythonsóquecomumasmágicasamais:).VocêpodeusartodososcomandosdoPythonaquitambém,éclaro.

Todososobjetos

Antes,vamostentarmostrartodasasnossaspostagens.Podemosfazerissocomoseguintecomando:

>>>Post.objects.all()

Traceback(mostrecentcalllast):

File"<console>",line1,in<module>

NameError:name'Post'isnotdefined

DjangoGirlsTutorial

86DjangoORM(Querysets)

Page 87: Djangogirls Tutorial Pt

Oops!Umerroapareceu.ElenosdizquenãoexistealgochamadoPost.Éverdade--nósesquecemosdeimportá-loprimeiro!

>>>fromblog.modelsimportPost

Issoésimples:importamosomodeloPostdedentrodoblog.models.Vamostentarmostrartodasaspostagensnovamente:

>>>Post.objects.all()

[<Post:myposttitle>,<Post:anotherposttitle>]

Éumalistadospostsquecriamosanteriormente!CriamosessespostsusandoainterfacedeadministraçãodoDjango.Noentanto,agoraqueremoscriarnovasmensagensutilizandoopython,entãocomoéquefazemosisso?

Criandoumobjeto

ÉassimquevocêcriaumobjetoPostnobancodedados:

>>>Post.objects.create(author=me,title='Sampletitle',text='Test')

Masaquitemosumingredientequefaltava:me.PrecisamospassarumainstânciadeUsermodelocomoautor.Comofazerisso?

PrimeirovamosimportaromodeloUser:

>>>fromdjango.contrib.auth.modelsimportUser

Quaisusuáriostemosnonossobancodedados?Experimenteisso:

>>>User.objects.all()

[<User:ola>]

Éosuperusuárioquecriamosanteriormente!Vamosobterumainstânciadeusuárioagora:

me=User.objects.get(username='ola')

Comovocêpodever,nósagorausamosumgetaUserwithausernameiguala'ola'.Claro,vocêtemqueadaptaraseunomedeusuário.

Agorafinalmentepodemoscriarnossaprimeirapostagem:

DjangoGirlsTutorial

87DjangoORM(Querysets)

Page 88: Djangogirls Tutorial Pt

>>>Post.objects.create(author=me,title='Sampletitle',text='Test')

Viva!Querversefuncionou?

>>>Post.objects.all()

[<Post:Sampletitle>]

Adicionemaispostagens

Agora,vocêpodesedivertirumpoucoeadicionarmaispostagensparavercomofunciona.Adicionemais2-3esigaparaapróximaparte.

Filtrarobjetos

UmagrandepartedeQuerySetséahabilidadedefiltrá-los.Digamosquequeremosencontrartodosaspostagensescritaspelousuárioola.NósusaremosofilteremvezdeallemPost.objects.all().Entreparêntesesindicamosqueascondiçõesprecisamseratendidasporumpostagemdeblogparaacabaremnossoqueryset.Emnossocasoéauthorqueéigualame.AmaneiradeescreverissonoDjangoé:author=me.Agoraonossotrechodecódigoparececomeste:

>>>Post.objects.filter(author=me)

[<Post:Sampletitle>,<Post:Postnumber2>,<Post:My3rdpost!>,<Post:4thtitleofpost>]

Outalveznósqueremosvertodosospostsquecontenhamapalavra'title'nocampodetitle?

>>>Post.objects.filter(title__contains='title')

[<Post:Sampletitle>,<Post:4thtitleofpost>]

NotaExistemdoiscaracteresdesublinhado(_)entreotitleecontains.DjangoORMusaestasintaxeparasepararnomesdecampo("title")eoperaçõesoufiltros("contains").Sevocêusarapenasumsublinhado,vocêobteráumerrocomo"FieldError:Cannotresolvekeywordtitle_contains".

Vocêtambémpodeobterumalistadetodosospostspublicados.Fazemosissofiltrandotodosospostscompublished_datedefinidonopassado:

fromdjango.utilsimporttimezonePost.objects.filter(published_date__lte=timezone.now())[]

DjangoGirlsTutorial

88DjangoORM(Querysets)

Page 89: Djangogirls Tutorial Pt

Infelizmente,nenhumdosnossospostsestãopublicadosainda.Nóspodemosmudarisso!Primeiroobtenhaumainstânciadeumpostquequeremospublicar:

>>>post=Post.objects.get(id=1)

Eentãopublicá-locomonossométododepublish!

>>>post.publish()

Agoratenteobteralistadepostspublicadosnovamente(pressioneasetaparacimabotão3vezesetecleEnter):

>>>Post.objects.filter(published_date__lte=timezone.now())

[<Post:Sampletitle>]

Ordenandoobjetos

UmQuerySettambémnospermiteordenaralistadeobjetos.Vamostentarordenaraspostagenspelocampocreated_date:

>>>Post.objects.order_by('created_date')

[<Post:Sampletitle>,<Post:Postnumber2>,<Post:My3rdpost!>,<Post:4thtitleofpost>]

Vocêtambémpodeinverteraordemadicionando-noinício:

>>>Post.objects.order_by('-created_date')

[<Post:4thtitleofpost>,<Post:My3rdpost!>,<Post:Postnumber2>,<Post:Sampletitle>]

Legal!Vocêjáestáprontoparaapróximaparte!Parafecharoterminaldigite:

>>>exit()

$

DjangoGirlsTutorial

89DjangoORM(Querysets)

Page 90: Djangogirls Tutorial Pt

DjangoQuerysetsNóstemosdiferentespeçasaqui:omodelPostestádefinidoemmodels.py,nóstemospost_listnoviews.pyeotemplateadicionado.MascomonósfaremosdefatoparafazercomqueasnossaspostagensapareçamnonossotemplateemHTML?Porqueéissoquenósqueremos:pegaralgumconteúdo(modelssalvosnobancodedados)eexibi-lodeumamaneirabacananonossotemplate,certo?

Eissoéexatamenteoqueasviewsdevemfazer:conectarmodelsetemplates.Nanossaviewpost_listviewnósvamosprecisarpegarosmodelsquequeremosexibirepassá-losparaotemplate.Então,basicamente,emumaviewnósdecidimosoque(ummodel)seráexibidonotemplate.

Certo,ecomonósfaremosisso?

Precisamosabrironossoblog/views.py.Atéagoraaviewpost_listseparececomisso:

fromdjango.shortcutsimportrender

defpost_list(request):

returnrender(request,'blog/post_list.html',{})

Lembraquandofalamossobreainclusãodecódigoescritoemarquivosdiferentes?Agoraéomomentoemquetemosdeincluiromodelquetemosescritoemmodels.py.Vamosadicionarestalinhafrom.modelsimportPostcomoeste:

fromdjango.shortcutsimportrender

from.modelsimportPost

Opontodepoisdefromsignificaodiretórioatualouoaplicativoatual.Comoviews.pyemodels.pyestãonomesmodiretóriopodemossimplesmenteusar.eonomedoarquivo(sem.py).Entãonósimportamosonomedomodelo(Post).

Eoquevemagora?ParapegarospostsreaisdomodelPostnósprecisamosdeumacoisachamadaQuerySet.

QuerySet

DjangoGirlsTutorial

90Dadosdinâmicosnostemplates

Page 91: Djangogirls Tutorial Pt

VocêjádeveestarfamiliarizadocomomodoqueosQuerySetsfuncionam.NósconversamossobreissonocapítuloORMdoDjango(QuerySets).</p>Agoranósestamosinteressadosemumalistadepostsquesãopublicadoseclassificadosporpublished_date,certo?NósjáfizemosissonocapítuloQuerySets!

Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')

Agoranóscolocamosestepedaçodecódigodentrodoarquivoblog/views.pyadicionando-oàfunçãodefpost_list(request):

fromdjango.shortcutsimportrender

fromdjango.utilsimporttimezone

from.modelsimportPost

defpost_list(request):

posts=Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date'

returnrender(request,'blog/post_list.html',{})

NotequecriamosumavariávelparanossooQuerySet:posts.TrateistocomoonomedonossoQuerySet.Deagoraemdiantenóspodemosnosreferiraeleporestenome.

AúltimapartequefaltaépassaroQuerySetpostsparaotemplate(veremoscomoexibi-loemumpróximocapítulo).

Nafunçãorenderjátemosoparâmetrorequest(tudooquerecebemosdousuárioatravésdaInternet)eumarquivodetemplate'blog/post_list.html'.Oúltimoparâmetro,queseparececomisso:{}éumlugaremquepodemosacrescentaralgumascoisasparaqueotemplateuse.Precisamosnomeá-los(ficaremoscom'posts'porenquanto:)).Deveficarassim:{'posts':posts}.Observequeaparteantesde:estáentreaspas''.

Entãofinalmentenossoarquivoblog/views.pydeveseparecercomisto:

fromdjango.shortcutsimportrender

fromdjango.utilsimporttimezone

from.modelsimportPost

defpost_list(request):

posts=Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date'

returnrender(request,'blog/post_list.html',{'posts':posts})

Feito!HoradevoltarparaonossotemplateeexibiressaQuerySet!

DjangoGirlsTutorial

91Dadosdinâmicosnostemplates

Page 92: Djangogirls Tutorial Pt

SequiserlermaissobreQuerySetsnoDjangovocêdevedarumaolhadaaqui:https://docs.djangoproject.com/en/1.8/ref/models/querysets/

DjangoGirlsTutorial

92Dadosdinâmicosnostemplates

Page 93: Djangogirls Tutorial Pt

TemplatesHoradeexibiralgumdado!Djangonosdátagsdetemplatesembutidasbastanteúteisparaisso.

Oquesãotagsdetemplate?Comopodever,vocênãopodecolocarcódigoPythonnoHTML,porqueosnavegadoresnãoirãoentender.ElesapenasconhecemHTML.NóssabemosqueHTMLébastanteestático,enquantoPythonémuitomaisdinâmico.

TagsdetemplateDjangonospermitetransformarobjetosPythonemcódigoHTML,paraquevocêpossaconstruirsitesdinâmicosmaisrápidoemaisfácil.Uhuu!

ModelodelistadepostdeexibiçãoNocapituloanterior,nósfornecemosaonossotemplateumalistadepostagenseavariávelposts.AgoravamosexibiremnossoHTML.

ParaexibirumavariávelnoDjangotemplate,nósusamoscolchetesduploscomonomedavariáveldentro,exemplo:

{{posts}}

Tentarfazerissonoseutemplateblog/templates/blog/post_list.html(substituiaosegundoeoterceiropardetags<div></div>pelalinha{{posts}}),salveoarquivoeatualizeapáginaparaverosresultados:

Vocêpodever,tudoquetemosé:

DjangoGirlsTutorial

93Templates

Page 94: Djangogirls Tutorial Pt

[<Post:Mysecondpost>,<Post:Myfirstpost>]

IstosignificaqueoDjangoaentendecomoumalistadeobjetos.Lembre-sedeintroduçãoaoPythoncomopodemosexibirlistas?Sim,comosloops!EmumtemplateDjango,fazemosissodaseguintemaneira:

{%forpostinposts%}

{{post}}

{%endfor%}

Tentefazerissonoseutemplate.

Funciona!Masnósqueremosqueelessejamexibidoscomoospostsestáticos,comoosquecriamosanteriormentenocapítulodeIntroduçãoaHTML.NóspodemosmisturarHTMLcomtagsdetemplate.Oconteúdodatagbodyficaráassim:

<div>

<h1><ahref="/">DjangoGirlsBlog</a></h1>

</div>

{%forpostinposts%}

<div>

<p>published:{{post.published_date}}</p>

<h1><ahref="">{{post.title}}</a></h1>

<p>{{post.text|linebreaks}}</p>

</div>

{%endfor%}

Tudoquevocêpõeenrte{%for%}e{%endfor%}serárepetidoparacadaobjetonalista.Atualizesuapágina:

DjangoGirlsTutorial

94Templates

Page 95: Djangogirls Tutorial Pt

Vocênotouquedessaveznósusamosumanotaçãoumpoucodiferente{{post.title}}ou{{post.text}}?NósestamosacessandoosdadosemcadaumdoscamposquedefinimosnomodeldoPost.Alémdisso,|linebreaksestápassandootextodopostporumfiltro,convertendoquebrasdelinhaemparágrafos.

MaisumacoisaSeriabomverseseusiteaindaestaráfuncionandonainternet,certo?VamostentarimplantaraPythonAnywherenovamente.Aquiestáumresumodospassos...

Primeiro,envieseucódigoparaoGithub

$gitstatus

$gitadd-A.

$gitstatus

$gitcommit-m"Addedviewstocreate/editblogpostinsidethesite."

$gitpush

Emseguida,façaloginemPythonAnywhereeváparaseuBashconsole(oucomeceumnovo)eexecute:

$cdmy-first-blog$gitpull

DjangoGirlsTutorial

95Templates

Page 96: Djangogirls Tutorial Pt

Finalmente,puleparaaWebtabeaperteReloademseuaplicativoweb.Suaatualizaçãodeveestarlive!

Parabéns!AgoraváemfrenteetenteadicionarumnovopostemseuDjangoadmin(Lembre-sedeadicionarpublished_date!),emseguida,atualizeapáginaparaverseopostapareceporlá.

Funcionacomomágica?Estamosorgulhosos!Afaste-sedoseucomputadorumpouco,vocêganhouumapausa.:)

DjangoGirlsTutorial

96Templates

Page 97: Djangogirls Tutorial Pt

CSS-Deixemaisbonito!Nossoblogaindaparecefeio,certo?Estánahoradedeixarelemelhor!ParaissonósusaremosoCSS.

OqueéCSS?Doinglês"CascadingStyleSheets",CSSéumalinguagemusadaparadescreveroaspectoeaformataçãodeumwebsiteescritonumalinguagemdemarcação(comoHTML).Imagineelecomosendoumtipode"maquiagem"paranossosite;).

Masnósnãoqueremosiniciardozerodenovo,certo?Nóstentaremos,maisumavez,usaralgoquefoifeitoedisponibilizadodegraçaporprogramadoresnainternet.Vocêsabe,reinventararodanãoénadadivertido.

VamosusaroBootstrap!BootstrapéumdosmaisfamososepopularesframeworksdeHTMLeCSSparadesenvolversitesbonitos:http://getbootstrap.com/

FoiescritoporprogramadoresquetrabalharamnoTwittereagoraédesenvolvidoporvoluntáriosdetodoomundo.

InstalarBootstrapParainstalaroBootstrap,vocêprecisaadicionaraoseucabeçalho(natag<head>dentrodoseuarquivo.html)(blog/templates/blog/post_list.html):

<linkrel="stylesheet"href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"

<linkrel="stylesheet"href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css"

Issonãoadicionanenhumarquivoaoseuprojeto.Ocódigoapenasapontaparaarquivosqueexistemnainternet.Apenassigaemfrente,abraseusiteeatualizeapágina.Aquieleestá!

DjangoGirlsTutorial

97CSS-Deixemaisbonito

Page 98: Djangogirls Tutorial Pt

Jáparecendomelhor!

ArquivosestáticosnoDjangoFinalmentenósteremosumolharmaisatentonessascoisasquechamamosarquivosestáticos.ArquivosestáticossãotodasassuasimagensearquivosCSS--arquivosquenãosãodinâmicos,entãoseuconteúdonãodependedocontextodarequisiçãoeseráomesmoparatodososusuários.

OndecolocarosarquivosestáticosparaDjango

Comovocêviuquandorodamoscollectstaticnoservidor,Djangojásabeondeencontrarosarquivosestáticosparaobuilt-in"admin"app.Agorasóprecisamosadicionaralgunsarquivosestáticosparanossopróprioapp,blog.

Fazemosissoatravésdacriaçãodeumapastachamadastaticdentrodoaplicativodoblog:

djangogirls

├──blog

│├──migrations

│└──static

└──mysite

Djangoencontraráautomaticamentetodasaspastaschamadas"static"dentrodequalquerumadaspastasdosseusapps,eserácapazdeusarseuconteúdocomoarquivosestáticos.

DjangoGirlsTutorial

98CSS-Deixemaisbonito

Page 99: Djangogirls Tutorial Pt

SeuprimeiroarquivoCSS!VamoscriarumarquivoCSSagora,paraadicionarseupróprioestiloparasuapáginadaweb.Crieumnovodiretóriochamadocssdentrodeseudiretóriostatic.Emseguida,crieumnovoarquivochamadoblog.cssdentrododiretóriocss.Pronto?

djangogirls

└───blog

└───static

└───css

└───blog.css

HoradeescreverCSS!Abraoarquivostatic/css/blog.cssnoseueditordecódigo.

NãovamosnosaprofundarmuitoemcustomizareaprendersobreCSSaqui,porqueébemfácilevocêpodeaprendernoseupróprioapósesteworkshop.RecomendamosfortementefazeresteCodeacademyHTML&CSScouseparaaprendertudooquevocêprecisasabersobrecomotornarseussitesmaisbonitoscomCSS.

Masvamosfazerpelomenosumpouco.Talvezpossamosmudaracordonossocabeçalho?Paraentenderascores,computadoresusamcódigosespeciais.Elescomeçamcom#esãoseguidospor6letras(A-F)enúmeros(0-9).Vocêpodeencontrarexemplosdecódigosdecoresaqui:http://www.colorpicker.com/.Vocêpodetambémusarcorespredefinidas,comoredegreen.

Emseuarquivostatic/css/blog.cssvocêdeveadicionaroseguintecódigo:

h1a{

color:#FCA205;

}

h1aéumseletordeCSS.Issosignificaquenósestamosaplicandonossosestilosparaqualquerelementoadentrodeumelementoh1(i.e.quandotivermosnocódigoalgocomo:<h1><ahref="">link</a></h1>).Nestecasonósestamosdizendoparamudaracorpara#FCA205,queélaranja.Claro,vocêpodecolocaracorquevocêquiseraqui!

EmumarquivoCSSpodemosdeterminarestilosparaelementosnoarquivoHTML.Oselementossãoidentificadospelonomedoelemento(ouseja,a,h1,body),oatributodeclassouoatributoid.Classeeidsãonomesquevocêmesmodáaoelemento.Classesdefinemgruposdeelementos,eidsapontamparaelementosespecíficos.Porexemplo,aseguintetagpodeseridentificadaporCSSusandoatagdenomea,aclasselink_externoouaidentificaçãodelink_para_a_pagina_wiki:

DjangoGirlsTutorial

99CSS-Deixemaisbonito

Page 100: Djangogirls Tutorial Pt

<ahref="http://en.wikipedia.org/wiki/Django"class="external_link"id="link_to_wiki_page"

LeiasobreSeletoresCSSemw3schools.

Então,precisamostambémcontaronossotemplateHTMLquenósadicionamosCSS.Abraoarquivoblog/templates/blog/post_list.htmleadicioneessalinhanoiníciodomesmo:

{%loadstaticfiles%}

Estamosapenascarregandoarquivosestáticosaqui:).Depois,entreo<head>e/</head>,depoisdoslinksparaosarquivosdeCSSdoBootstrap(onavegadorlêosarquivosnaordemqueelessãodados,entãoocódigoemnossoarquivopodesubstituirocódigoemarquivosdeinicialização),adicioneestalinha:

<linkrel="stylesheet"href="{%static'css/blog.css'%}">

SódissemosquenossomodeloondeseencontranossoarquivoCSS.

Agora,seuarquivodeveficarassim:

{%loadstaticfiles%}

<html>

<head>

<title>DjangoGirlsblog</title>

<linkrel="stylesheet"href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"

<linkrel="stylesheet"href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css"

<linkrel="stylesheet"href="{%static'css/blog.css'%}">

</head>

<body>

<div>

<h1><ahref="/">DjangoGirlsBlog</a></h1>

</div>

{%forpostinposts%}

<div>

<p>published:{{post.published_date}}</p>

<h1><ahref="">{{post.title}}</a></h1>

<p>{{post.text|linebreaks}}</p>

</div>

{%endfor%}

</body>

</html>

OK,salveoarquivoeatualizeosite!

DjangoGirlsTutorial

100CSS-Deixemaisbonito

Page 101: Djangogirls Tutorial Pt

Bomtrabalho!Talvezagentetambémqueiradarumpoucodearaonossositeeaumentaramargemdoladoesquerdo?Vamostentar!

body{

padding-left:15px;

}

AdicioneistoaoseuarquivoCSS,salveevejacomoelefunciona!

Talvezagentepossacustomizarafontenonossocabeçalho?Colenaseção<head>doarquivoblog/templates/blog/post_list.htmloseguinte:

<linkhref="http://fonts.googleapis.com/css?family=Lobster&subset=latin,latin-ext"rel="stylesheet"

DjangoGirlsTutorial

101CSS-Deixemaisbonito

Page 102: Djangogirls Tutorial Pt

EssalinhairáimportarumafontechamadaLobsterdoGoogleFonts(https://www.google.com/fonts).

Agoraadicionealinhafont-family:'Lobster';noCSSdoarquivostatic/css/blog.cssdentrodoblocodedeclaraçãoh1a(ocódigoentreaschaves{e})eatualizeapágina:

h1a{

color:#FCA205;

font-family:'Lobster';

}

Incrível!

Comomencionadoacima,CSSusaoconceitodeclasses,quebasicamentepermitequevocênomeiepartedocódigoHTMLeapliqueestilosapenasàestaparte,semafetarasoutras.Ésuperútilsevocêtiverduasdivs,maselesestãofazendoalgomuitodiferente(comooseucabeçalhoeseupost),entãovocênãoquerqueelesfiquemparecidos.

VáemfrenteeonomeiealgumaspartesdocódigoHTML.Adicioneumaclassechamadadepage-headerparaodivquecontémocabeçalho,assim:

<divclass="page-header">

<h1><ahref="/">DjangoGirlsBlog</a></h1>

</div>

Eagora,adicioneumaclassepostemsuadivquecontémumpostdeblog.

DjangoGirlsTutorial

102CSS-Deixemaisbonito

Page 103: Djangogirls Tutorial Pt

<divclass="post">

<p>published:{{post.published_date}}</p>

<h1><ahref="">{{post.title}}</a></h1>

<p>{{post.text|linebreaks}}</p>

</div>

Agoraadicionaremosblocosdedeclaraçãodeseletoresdiferentes.Seletorescomeçandocom.sereferemàsclasses.ExistemmuitostutoriaiseexplicaçõessobreCSSnaWebparaajudarvocêaentenderocódigoaseguir.Porenquanto,bastacopiarecolá-loemseuarquivomysite/static/css/blog.css:

DjangoGirlsTutorial

103CSS-Deixemaisbonito

Page 104: Djangogirls Tutorial Pt

.page-header{

background-color:#ff9400;

margin-top:0;

padding:20px20px20px40px;

}

.page-headerh1,.page-headerh1a,.page-headerh1a:visited,.page-headerh1a:active{

color:#ffffff;

font-size:36pt;

text-decoration:none;

}

.content{

margin-left:40px;

}

h1,h2,h3,h4{

font-family:'Lobster',cursive;

}

.date{

float:right;

color:#828282;

}

.save{

float:right;

}

.post-formtextarea,.post-forminput{

width:100%;

}

.top-menu,.top-menu:hover,.top-menu:visited{

color:#ffffff;

float:right;

font-size:26pt;

margin-right:20px;

}

.post{

margin-bottom:70px;

}

.posth1a,.posth1a:visited{

color:#000000;

}

EntãoenvolvaocódigoHTMLqueexibeasmensagenscomdeclaraçõesdeclasses.Substituaisto:

DjangoGirlsTutorial

104CSS-Deixemaisbonito

Page 105: Djangogirls Tutorial Pt

{%forpostinposts%}

<divclass="post">

<p>published:{{post.published_date}}</p>

<h1><ahref="">{{post.title}}</a></h1>

<p>{{post.text|linebreaks}}</p>

</div>

{%endfor%}

noarquivoblog/templates/blog/post_list.htmlporisto:

<divclass="contentcontainer">

<divclass="row">

<divclass="col-md-8">

{%forpostinposts%}

<divclass="post">

<divclass="date">

{{post.published_date}}

</div>

<h1><ahref="">{{post.title}}</a></h1>

<p>{{post.text|linebreaks}}</p>

</div>

{%endfor%}

</div>

</div>

</div>

Salveessesarquivoseatualizeseusite.

Uhuu!Ficouincrível,né?Ocódigoquenósacabamosdecolarnãoétãodifícildeentenderevocêdevesercapazdeentenderamaiorparteapenaslendo.

NãotenhamedodemexerumpoucocomesseCSSetentarmudaralgumascoisas.Sevocêquebraralgumacoisa,nãosepreocupe,vocêsemprepodedesfazê-lo!

DjangoGirlsTutorial

105CSS-Deixemaisbonito

Page 106: Djangogirls Tutorial Pt

Dequalquerforma,recomendamosquefaçaessecursoon-lineCodeacademyHTML&CSSCoursecomodeverdecasapós-workshopparaaprendertudooquevocêprecisasabersobrecomotornarseussitesmaisbonitoscomCSS.

Prontoparaopróximocapítulo?!:)

DjangoGirlsTutorial

106CSS-Deixemaisbonito

Page 107: Djangogirls Tutorial Pt

EstendendoostemplatesOutracoisaboaqueoDjangotempravocêéotemplateextending.Oqueissosignifica?IssosignificaquevocêpodeusarasmesmaspartesdoseuHTMLemdiferentespáginasdoseusite.

Dessaformavocênãoprecisaficarserepetindoemcadaarquivoquandoquiserusaramesmainformação/layout.Esevocêquisermudaralgumacoisanãoprecisafazerissoemtodotemplate,sóumavez!

CriartemplatebaseUmtemplatebaseéotemplatemaisbásicoquevocêestenderáemcadapáginadoseusite.

Vamoscriarumarquivobase.htmlnapastablog/templates/blog/:

blog

└───templates

└───blog

base.html

post_list.html

Abra-oecopietudoqueestánoarquivopost_list.htmlparabase.html,dessejeito:

DjangoGirlsTutorial

107Estendendoostemplates

Page 108: Djangogirls Tutorial Pt

{%loadstaticfiles%}

<html>

<head>

<title>DjangoGirlsblog</title>

<linkrel="stylesheet"href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"

<linkrel="stylesheet"href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css"

<linkhref='//fonts.googleapis.com/css?family=Lobster&subset=latin,latin-ext'rel

<linkrel="stylesheet"href="{%static'css/blog.css'%}">

</head>

<body>

<divclass="page-header">

<h1><ahref="/">DjangoGirlsBlog</a></h1>

</div>

<divclass="contentcontainer">

<divclass="row">

<divclass="col-md-8">

{%forpostinposts%}

<divclass="post">

<divclass="date">

{{post.published_date}}

</div>

<h1><ahref="">{{post.title}}</a></h1>

<p>{{post.text|linebreaks}}</p>

</div>

{%endfor%}

</div>

</div>

</div>

</body>

</html>

Entãoembase.html,substituatodoseu<body>(tudoentre<body>e</body>)comisso:

<body>

<divclass="page-header">

<h1><ahref="/">DjangoGirlsBlog</a></h1>

</div>

<divclass="contentcontainer">

<divclass="row">

<divclass="col-md-8">

{%blockcontent%}

{%endblock%}

</div>

</div>

</div>

</body>

DjangoGirlsTutorial

108Estendendoostemplates

Page 109: Djangogirls Tutorial Pt

Basicamentenóssubstituimostudoentre{%forpostinposts%}{%endfor%}por:

{%blockcontent%}

{%endblock%}

Oqueissosignifica?Vocêacaboudecriarumblock(bloco),queéumatagdetemplatequetepermiteinserirHTMLnesteblocoemoutrostemplatesqueestendembase.html.Nósvamostemostrarcomofazerissojájá.

Salveeabraoarquivoblog/templates/blog/post_list.htmlnovamente.Apagueexatamentetudoquenãoestiverdentrodatagbodyeapaguetambém<divclass="page-header"></div>,deformaqueoarquivofiquedaseguintemaneira:

{%forpostinposts%}

<divclass="post">

<divclass="date">

{{post.published_date}}

</div>

<h1><ahref="">{{post.title}}</a></h1>

<p>{{post.text|linebreaks}}</p>

</div>

{%endfor%}

Agoraadicioneestalinhaaoiníciodoarquivo:

{%extends'blog/base.html'%}

Issosignificaque,agora,nósestamosestendendootemplatebase.htmlempost_list.html.Umaúltimacoisa:colocartudo(excetopelalinhaqueacabamosdeadicionar)entre{%blockcontent%}e{%endblockcontent%}.Comoaseguir:

{%extends'blog/base.html'%}

{%blockcontent%}

{%forpostinposts%}

<divclass="post">

<divclass="date">

{{post.published_date}}

</div>

<h1><ahref="">{{post.title}}</a></h1>

<p>{{post.text|linebreaks}}</p>

</div>

{%endfor%}

{%endblockcontent%}

DjangoGirlsTutorial

109Estendendoostemplates

Page 110: Djangogirls Tutorial Pt

Éisso!Vejaseoseusiteaindaestáfuncionandodireito:)

SeocorrerumerrodeTemplateDoesNotExists,quedizquenãoexistenenhumarquivochamadoblog/base.htmlesevocêtiverorunserverexecutandonoterminal,tentainterrompê-lo(precionandoCtrl+C-obotãoControlmaisobotãoCjuntos)ereinicieelerodandoocomandopythonmanage.pyrunserver.

DjangoGirlsTutorial

110Estendendoostemplates

Page 111: Djangogirls Tutorial Pt

AmpliesuaaplicaçãoJáconcluímostodosospassosnecessáriosparaacriaçãodonossosite:sabemoscomocriarummodelo,umaurl,umavieweumtemplate.Tambémsabemoscomomelhoraraaparênciadonossowebsite.

Horadepraticar!

Aprimeiraqueprecisamosnonossoblogé,obviamente,umapáginaparamostrarumapostagem,certo?

JátemosummodelodePost,entãonãoprecisamosadicionarnadaaomodels.py.

CriarumlinknotemplateVamoscomeçarcomaadiçãodeumlinkdentrodoarquivoblog/templates/blog/post_list.html.Nestemomentoeledeveseparecercom:

{%extends'blog/base.html'%}

{%blockcontent%}

{%forpostinposts%}

<divclass="post">

<divclass="date">

{{post.published_date}}

</div>

<h1><ahref="">{{post.title}}</a></h1>

<p>{{post.text|linebreaks}}</p>

</div>

{%endfor%}

{%endblockcontent%}

Queremosterumlinkparaumapáginadedetalhenotítulodopost.Vamostransformar<h1><href="">{{post.title}}</a></h1>emumlink:

<h1><ahref="{%url'blog.views.post_detail'pk=post.pk%}">{{post.title}}</a></h1>

Tempoparaexplicaromisterioso{%url'blog.views.post_detail'pk=post.pk%}.Comovocêpodesuspeitar,anotaçãode{%%}significaqueestamosusandoastagsdetemplatedoDjango.DestavezvamosusarumaquevaicriarumaURLparanós!

DjangoGirlsTutorial

111Ampliesuaaplicação

Page 112: Djangogirls Tutorial Pt

blog.views.post_detailéumcaminhoparaumpost_detailVistaquequeremoscriar.Presteatenção:blogéonomedasuaaplicação(odiretórioblog),viewsvemdonomedoarquivoviews.pye,aúltimaparte-post_detail-éonomedaview.

Agoraquandoformospara:http://127.0.0.1:8000/teremosumerro(comoesperado,jáquenãotemosumaURLouumaviewparapost_detail).Vaiseparecercomisso:

VamoscriaraURLemurls.pyparaanossapost_detailview!

URL:http://127.0.0.1:8000/post/1/

QueremoscriarumaURLparaguiaroDjangoparaaviewchamadapost_detail,queirámostrarumpostcompletodoblog.Adicionealinhaurl(r'^post/(?P<pk>[0-9]+)/$',views.post_detail),aoarquivoblog/urls.py.Deveficarassim:

fromdjango.conf.urlsimportinclude,url

from.importviews

urlpatterns=[

url(r'^$',views.post_list),

url(r'^post/(?P<pk>[0-9]+)/$',views.post_detail),

]

Pareceassustador,masnãosepreocupe-vamosexplicareleparavocê:-começacom

denovo..."oinício"-post/significaapenasqueapósocomeço,daURLdeveterapalavraposte/.Atéaqui,tudobem.-(?P<pk>[0-9]+)-essaparteémaiscomplicada.IssosignificaqueoDjangovailevartudoquevocêcolocaraquietransferirparaumaviewcomoumavariávelchamadapk.[0-9]tambémnosdizquesópodeserumnúmero,nãoumaletra(tudoentre0e9).+significaqueprecisaexistirumoumaisdígitos.Entãoalgocomohttp://127.0.0.1:8000/post//nãoéválido,mashttp://127.0.0.1:8000/post/1234567890/éperfeitamenteok!-/-entãoprecisamosde/outravez-$-"ofim"!

DjangoGirlsTutorial

112Ampliesuaaplicação

Page 113: Djangogirls Tutorial Pt

Issosignificaquesevocêdigitarhttp://127.0.0.1:8000/post/5/emseunavegador,Djangovaientenderquevocêestáprocurandoumaviewchamadapost_detailetransferirainformaçãodequepkéiguala5paraaquelaview.

pkéumaabreviaçãoparaprimarykey(chaveprimária).EssenomegeralmenteéusadonosprojetosfeitosemDjango.Masvocêpodedaronomequequiseràsvariáveis(lembre-se:minúsculoe_aoinvésdeespaçosembranco!).Porexemploemvezde(?P<pk>[0-9]+)podemosterumavariávelpost_id,entãoestaparteficariacomo:(?P<post_id>[0-9]+).

Razoável!Vamosatualizarapágina:http://127.0.0.1:8000/Boom!Aindaoutroerro!Comoesperado!

Vocêselembraqualéopróximopasso?Claro:adicionandoumaview!

post_detailviewDestavezanossaviewrecebeumparâmetroextrapk.Nossaviewprecisapegá-la,certo?Entãovamosdefinirnossafunçãocomodefpost_detail(request,pk):.Observequeprecisamosusarexatamenteomesmonomequeespecificamosemurls(pk).Omitiressavariáveléerradoeresultaráemumerro!

Agoraqueremosreceberapenasumpostdoblog.Paraissopodemosusarquerysetscomoeste:

Post.objects.get(pk=pk)

Masestecódigotemumproblema.SenãohouvernenhumPostcomachaveprimária(pk)fornecidateremosumerrohorroroso!

DjangoGirlsTutorial

113Ampliesuaaplicação

Page 114: Djangogirls Tutorial Pt

Nãoqueremosisso!Mas,claro,oDjangovemcomalgoquevailidarcomissoparanós:get_object_or_404.CasonãohajanenhumPostcomodadopkexibiráumapáginamuitomaisagradável(chamadaPageNotFound404-páginanãoencontrada).

AboanotíciaéquevocêrealmentepodecriarsuaprópriapáginadePagenotfoundetorná-lotãobonitaquantovocêquiser.Masissonãoésuperimportanteagora,entãonósvamosignorá-la.

Ok,horadeadicionarumaviewaonossoarquivoviews.py!

Devemosabrirblog/views.pyeadicionaroseguintecódigo:

fromdjango.shortcutsimportrender,get_object_or_404

Pertodeoutraslinhasfrom.Enofinaldoarquivo,adicionaremosanossaview:

defpost_detail(request,pk):

post=get_object_or_404(Post,pk=pk)

returnrender(request,'blog/post_detail.html',{'post':post})

Sim.Estánahoradeatualizarapágina:http://127.0.0.1:8000/

DjangoGirlsTutorial

114Ampliesuaaplicação

Page 115: Djangogirls Tutorial Pt

Funcionou!Masoqueacontecequandovocêclicaemumlinknotítulodopostdoblog?

Ahnão!Outroerro!Masnósjásabemoscomolidarcomisso,né?Precisamosadicionarumtemplate!

Vamoscriarumarquivoemblog/templates/blogchamadopost_detail.html.

Seráalgoparecidocomisto:

DjangoGirlsTutorial

115Ampliesuaaplicação

Page 116: Djangogirls Tutorial Pt

{%extends'blog/base.html'%}

{%blockcontent%}

<divclass="post">

{%ifpost.published_date%}

<divclass="date">

{{post.published_date}}

</div>

{%endif%}

<h1>{{post.title}}</h1>

<p>{{post.text|linebreaks}}</p>

</div>

{%endblock%}

Maisumavezestamosestendendobase.html.Noblocodecontentqueremosexibiropublished_date(datadepublicação)dopost(sehouver),títuloetexto.Masdevemosdiscutiralgumascoisasimportantes,certo?

{%if...%}...{%endif%}éumatagdetemplatequepodemosusarquandoqueremosverificaralgo(Lembre-seif...else...docapítulointroduçãoaoPython?).Nestecenário,queremosverificarsepublished_datedeumpostnãoestávazia.

Ok,podemosatualizarnossapáginaeversePagenotfoundjásefoi.

Yay!Funciona!

DjangoGirlsTutorial

116Ampliesuaaplicação

Page 117: Djangogirls Tutorial Pt

Maisumacoisa:horadeimplantar!SeriabomverseseusiteaindaestarátrabalhandoemPythonAnywhere,certo?Vamostentarfazerdeploynovamente.

$gitstatus

$gitadd-A.

$gitstatus

$gitcommit-m"Addedviewstocreate/editblogpostinsidethesite."

$gitpush

Então,emumconsolePythonAnywhereBash:

$cdmy-first-blog

$gitpull

Finalmente,puleparaaWebtabeaperteReload.Edeveserisso!Parabéns:)

DjangoGirlsTutorial

117Ampliesuaaplicação

Page 118: Djangogirls Tutorial Pt

FormuláriosPorúltimoqueremosumaformalegaldeadicionareeditaraspostagensdonossoblog.AferramentadeadministraçãodoDjangoélegal,maselaéumpoucodifícildecustomizarededeixarmaisbonita.Seusarmosformuláriosteremoscontroleabsolutosobrenossainterface-podemosfazerqualquercoisaqueimaginarmos!

UmacoisalegaldoDjangoéquenóspodemostantocriarumformuláriodozerocomopodemoscriarumModelFormquesalvaoresultadodoformulárioparaumdeterminadomodelo.

Issoéexatamenteoquenósqueremosfazer:criaremosumformulárioparaonossomodeloPost.

AssimcomotodaparteimportantedoDjango,formstemseupróprioarquivo:forms.py.

Precisamoscriarumarquivocomestenomedentrodapastablog.

blog

└──forms.py

Ok,vamosabri-loeescreverneleoseguinte:

fromdjangoimportforms

from.modelsimportPost

classPostForm(forms.ModelForm):

classMeta:

model=Post

fields=('title','text',)

PrimeiroprecisamosimportaromódulodeformuláriosdoDjango(fromdjangoimportforms)e,obviamente,nossomodeloPost(from.modelsimportPost).

PostForm,comovocêjádevesuspeitar,éonomedonossoformulário.PrecisamosdizeraoDjangoqueesteformulárioéumModelForm(assimoDjangopodefazeramágicapragente)-oforms.ModelForméoresponsávelporisso.

Segundo,nóstemosaclasseMetaondedizemosaoDjangoqualmodelodeveriaserusadoparacriaresteformulário(model=Post).

DjangoGirlsTutorial

118Formulários

Page 119: Djangogirls Tutorial Pt

Finalmente,nóspodemosdizerqual(is)campo(s)deveriamentraremnossoformulário.Nessecenárionósqueremosapenasotitleetextparaserexposto-authordeveriaserapessoaqueestálogadanosistema(nessecaso,você!)ecreated_datedeveriasersetadoautomaticamentequandonóscriamosumpost(nocódigo),correto?

Eéissoaí!Tudooqueprecisamosfazeragoraéusaroformulárioemumaviewemostrá-loemumtemplate.

Então,maisumavez,nósiremoscriar:umlinkparaapágina,umaURL,umavieweumtemplate.

LinkparaapáginacomoformulárioÉhoradeabrirblog/templates/blog/base.html.Nósiremosadicionarumlinkemdivnomeadopage-header:

<ahref="{%url'blog.views.post_new'%}"class="top-menu"><spanclass="glyphiconglyphicon-plus"

Notequenósqueremoschamarnossanovavisãopost_new.

Depoisdeadicionaralinha,seuhtmldeveseparecercomisso:

DjangoGirlsTutorial

119Formulários

Page 120: Djangogirls Tutorial Pt

{%loadstaticfiles%}

<html>

<head>

<title>DjangoGirlsblog</title>

<linkrel="stylesheet"href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"

<linkrel="stylesheet"href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css"

<linkhref='//fonts.googleapis.com/css?family=Lobster&subset=latin,latin-ext'rel

<linkrel="stylesheet"href="{%static'css/blog.css'%}">

</head>

<body>

<divclass="page-header">

<ahref="{%url'blog.views.post_new'%}"class="top-menu"><spanclass="glyphiconglyphicon-plus"

<h1><ahref="/">DjangoGirlsBlog</a></h1>

</div>

<divclass="contentcontainer">

<divclass="row">

<divclass="col-md-8">

{%blockcontent%}

{%endblock%}

</div>

</div>

</div>

</body>

</html>

Depoisdesalvarerecarregarapáginahttp://127.0.0.1:8000vocêverá,obviamente,umerrofamiliarNoReverseMatchcerto?

URLVamosabriroarquivoblog/urls.pyeescrever:

url(r'^post/new/$',views.post_new,name='post_new'),

Ocódigofinaldeveseparecercomisso:

fromdjango.conf.urlsimportinclude,url

from.mportviews

urlpatterns=[

url(r'^$',views.post_list),

url(r'^post/(?P<pk>[0-9]+)/$',views.post_detail),

url(r'^post/new/$',views.post_new,name='post_new'),

]

DjangoGirlsTutorial

120Formulários

Page 121: Djangogirls Tutorial Pt

Apósrecarregarosite,nósveremosumAttributeError,desdequenósnãotemosavisãopost_newimplementada.Vamosadicioná-laagora.

post_newviewHoradeabriroarquivoblog/views.pyeadicionaraslinhasseguintescomorestodaslinhasfrom:

from.formsimportPostForm

enossaview:

defpost_new(request):

form=PostForm()

returnrender(request,'blog/post_edit.html',{'form':form})

ParacriarumnovoformularioPost,nósdevemoschamarPostForm()epassá-loparaotemplate.Nósiremosvoltarparaestaview,masporagoravamoscriarrapidamenteumtemplateparaoformulário.

Template(modelos)Precisamoscriarumarquivopost_edit.htmlnapastablog/templates/blog.Prafazeroformuláriofuncionarprecisamosdemuitascoisas:

Temosqueexibiroformulário.Podemosfazerissosimplesmentecomum``.AlinhaacimaprecisaestardentrodeumatagHTMLform:<formmethod="POST">...</form>

PrecisamosdeumbotãoSalvar.FazemosissocomumbotãoHTML:<buttontype="submit">Save</button>

Efinalmente,depoisdeabriratag<form...>precisamosadicionarum{%csrf_token%}.Issoémuitoimportante,poiséissoquefazonossoformulárioficarseguro!ODJangovaireclamarsevocêesquecerdeadicionarissoesimplesmentesalvaroformulário:

DjangoGirlsTutorial

121Formulários

Page 122: Djangogirls Tutorial Pt

Beleza,entãovamosvercomoficouoHTMLpost_edit.html:

{%extends'blog/base.html'%}

{%blockcontent%}

<h1>Newpost</h1>

<formmethod="POST"class="post-form">{%csrf_token%}

{{form.as_p}}

<buttontype="submit"class="savebtnbtn-default">Guardar</button>

</form>

{%endblock%}

Horadeatualizar!Há!Seuformulárioapareceu!

DjangoGirlsTutorial

122Formulários

Page 123: Djangogirls Tutorial Pt

Mas,espereumminuto!Quandovocêdigitaalgumacoisanoscampostitleetextetentasalvaroqueacontece?

Nada!Estamosnovamentenamesmapáginaenossotextosumiu...Enenhumpostfoiadicionado.Entãooquedeuerrado?

Arespostaé:nada.Precisamostrabalharumpoucomaisnanossaview.

SalvandooformulárioAbrablog/views.pymaisumavez.Atualmentetudoquetemosnavisãopost_newé:

defpost_new(request):

form=PostForm()

returnrender(request,'blog/post_edit.html',{'form':form})

Quandonósenviamosoformulário,somostrazidosdevoltaparaamesmavisão,masdestaveztemosmaisalgunsdadosnorequest,maisespecificamenteemrequest.POST(onomenãotemnadacom"post"deblog,temavercomofatodequeestamos"postando"dados).VocêselembraquenoarquivoHTMLnossadefiniçãode<form>tema

DjangoGirlsTutorial

123Formulários

Page 124: Djangogirls Tutorial Pt

variávelmethod="POST"?Todososcamposvindosdo"form"estarãodisponíveisagoraemrequest.POST.VocênãodeveriarenomearPOSTparanadadiferentedisso(oúnicooutrovalorválidoparamethodéGET,masnósnãotemostempoparaexplicarqualéadiferença).

Entãonanossaviewnóstemosduassituaçõesseparadasparalidar.Aprimeiraéquantoacessamosapáginapelaprimeiravezequeremosumformulárioembranco.Easegunda,équandonóstemosquevoltarparaaviewcomtodososdadosdoformulárioquenósdigitamos.Dessemodo,precisamosadicionarumacondição(usaremosifparaisso).

ifrequest.method=="POST":

[...]

else:

form=PostForm()

Estánahoradepreencherospontos[...].SemethodéPOSTentãonósqueremosconstruiroPostFormcomosdadosqueveemdoformulário,certo?Nósiremosfazerassim:

form=PostForm(request.POST)

Fácil!Próximacoisaéverificarseoformulárioestácorreto(todososcamposrequeridossãodefinidosevaloresincorretosnãoserãosalvos).Fazemosissocomform.is_valid().

Verificamosseoformulárioéválidoeseestivertudocerto,podemossalvá-lo!

ifform.is_valid():

post=form.save(commit=False)

post.author=request.user

post.save()

Basicamente,temosduascoisasaqui:Salvamosoformuláriocomform.saveeadicionadosumautor(desdequenãohajaocampoauthoremPostForm,eestecampoéobrigatório!).commit=FalsesignificaquenãoqueremossalvaromodeloPostainda-queremosadicionarautorprimeiro.Namaioriadasvezesvocêiráusarform.save(),semcommit=False,masnestecaso,precisamosfazerisso.post.save()irápreservarasalterações(adicionandoautor)eécriadoumnovopostnoblog!

Finalmente,nãoseriafantásticosenóspudéssemosimediatamenteiràpáginadepost_detailparaorecém-criadoblogpost,certo?Parafazerissonósprecisaremosdemaisumaimportação:

DjangoGirlsTutorial

124Formulários

Page 125: Djangogirls Tutorial Pt

fromdjango.shortcutsimportredirect

Adicione-ologonoiníciodoseuarquivo.Eagorapodemosdizer:váparaapáginapost_detailparaumrecém-criadopost.

returnredirect('blog.views.post_detail',pk=post.pk)

blog.views.post_detailéonomedaviewquequeremosir.Lembre-sequeessaviewexigeumavariávelpk?Parapassarissonasviewsusamospk=post.pk,ondepostéorecém-criadoblogpost.

Ok,nósfalamosmuito,masprovavelmentequeremosveroquetodaaviewirápareceragora,certo?

defpost_new(request):

ifrequest.method=="POST":

form=PostForm(request.POST)

ifform.is_valid():

post=form.save(commit=False)

post.author=request.user

post.save()

returnredirect('blog.views.post_detail',pk=post.pk)

else:

form=PostForm()

returnrender(request,'blog/post_edit.html',{'form':form})

Vamosversefunciona.Váparaopáginahttp://127.0.0.1:8000/post/novo/,adicioneumtitleeotext,salve...evoilà!Onovoblogpostéadicionadoenóssomosredirecionadosparaapáginadepost_detail!

Vocêprovavelmentenotouquenósnãoestamosdefinindoadatadepublicaçãoemtudo.VamosintroduzirumbotãodepublicaçãoemDjangoGirlsTutorial:Extensões.

Issoéincrível!

ValidaçãodeformuláriosAgora,nóslhemostraremoscomoosfórmulariossãolegais.Opostdoblogprecisateroscampostitleetext.EmnossomodeloPostnãodissemos(emoposiçãoapublished_date)queessescamposnãosãonecessários,entãoDjango,porpadrão,espera-osaserdefinido.

Tentesalvaroformuláriosemtitleetext.Adivinheoquevaiacontecer!

DjangoGirlsTutorial

125Formulários

Page 126: Djangogirls Tutorial Pt

Djangoestátomandocontadevalidarsetodososcamposdenossoformulárioestãocorretos.Nãoéincrível?

ComorecentementeusamosainterfacedeadministraçãodoDjangoosistemaentendequeestamoslogados.Existemalgumassituaçõesquepoderiamlevarasermosdeslogadosdosistema(fecharonavegador,reiniciarbancodedadosetc.).Sevocêperceberqueerrosestãoaparecendoaocriarumpostquereferenciaumusuárioquenãoestálogado,váparaapáginaadminhttp://127.0.0.1:8000eloguenovamente.Issovairesolveroproblematemporariamente.Háumajustepermanenteesperandoporvocêemliçãodecasa:adicionarsegurançanoseusite!,capítuloapósotutorialprincipal.

DjangoGirlsTutorial

126Formulários

Page 127: Djangogirls Tutorial Pt

EditandooformulárioAgorasabemoscomoadicionarumnovoformulário.Masesequisermoseditarumjáexistente?Émuitosemelhanteaoquefizemos.Vamoscriaralgumascoisasimportantesrapidamente(sevocênãoentenderalgumacoisa-vocêdeveperguntaraseuprofessorouvejaoscapítulosanteriores,jácobrimostodasessasetapasanteriormente).

Abrablog/templates/blog/post_detail.htmleadicionealinha:

<aclass="btnbtn-default"href="{%url'post_edit'pk=post.pk%}"><spanclass="glyphiconglyphicon-pencil"

Agoraomodeloestaráparecidocom:

{%extends'blog/base.html'%}

{%blockcontent%}

<divclass="date">

{%ifpost.published_date%}

{{post.published_date}}

{%endif%}

<aclass="btnbtn-default"href="{%url'post_edit'pk=post.pk%}"><spanclass="glyphiconglyphicon-pencil"

</div>

<h1>{{post.title}}</h1>

<p>{{post.text|linebreaks}}</p>

{%endblock%}

Emblog/urls.pyadicionamosestalinha:

url(r'^post/(?P<pk>[0-9]+)/edit/$',views.post_edit,name='post_edit'),

Nósreutilizaremosomodeloblog/templates/blog/post_edit.html,entãoaúltimacoisaquefaltaéumaview.

Vamosabrirblog/views.pyeadicionarnofinaldoarquivo:

DjangoGirlsTutorial

127Formulários

Page 128: Djangogirls Tutorial Pt

defpost_edit(request,pk):

post=get_object_or_404(Post,pk=pk)

ifrequest.method=="POST":

form=PostForm(request.POST,instance=post)

ifform.is_valid():

post=form.save(commit=False)

post.author=request.user

post.save()

returnredirect('blog.views.post_detail',pk=post.pk)

else:

form=PostForm(instance=post)

returnrender(request,'blog/post_edit.html',{'form':form})

Issoéquaseexatamenteigualanossaviewdepost_new,certo?Masnãototalmente.Primeiracoisa:passamosumparâmetroextradaurlpk.Emseguida:pegamosomodeloPostquequeremoseditarcomget_object_or_404(Post,pk=pk)eentão,quandocriamosumformuláriopassamosestepostcomoumainstância,tantoquandosalvamosoformulário:

form=PostForm(request.POST,instance=post)

comoquandonósapenasabrimosumformuláriocomestepostparaeditar:

form=PostForm(instance=post)

Ok,vamostestarsefunciona!Vamosparaapáginapost_detail.Devehaverumbotãoeditarnocantosuperiordireito:

DjangoGirlsTutorial

128Formulários

Page 129: Djangogirls Tutorial Pt

Quandovocêclicarnelevocêveráoformuláriocomanossapostagem:

Sinta-selivreparamudarotítuloouotextoesalvarasmudanças!

Parabéns!Suaaplicaçãoestáficandocadavezmaiscompleta!

DjangoGirlsTutorial

129Formulários

Page 130: Djangogirls Tutorial Pt

SevocêprecisardemaisinformaçõessobreformuláriosdoDjangovocêdeveleradocumentação:https://docs.djangoproject.com/en/1.8/topics/forms/

Maisumacoisa:horadeimplantar!VamosversetudoissofuncionanaPythonAnywhere.Tempoparaoutrodeploy!

Primeiro,commitoseunovocódigoecoloquenoGithub

$gitstatus

$gitadd-A.

$gitstatus

$gitcommit-m"Addedviewstocreate/editblogpostinsidethesite."

$gitpush

Então,emumconsolePythonAnywhereBash:

$cdmy-first-blog

$gitpull

Finalmente,puleparaaWebtabeaperteReload.Edeveserisso!Parabéns:)

DjangoGirlsTutorial

130Formulários

Page 131: Djangogirls Tutorial Pt

DomínioPythonAnywheretedeuumdomíniogratuito,mastalvezvocênãoqueirater".pythonanywhere.com"nofinaldaURLdoseublog.Talvezvocêqueiraseublogapenas"www.infinite-kitten-pictures.org"ou"www.3d-printed-steam-engine-parts.com"ou"www.antique-buttons.com"ou"www.mutant-unicornz.net",ousejaoquevaiser.

Aquivamosfalarumpoucosobreondeobterumdomínioecomoligá-loaseuaplicativodawebemPythonAnywhere.Noentanto,vocêdevesaberqueamaioriadosdomínioscustamdinheiroePythonAnyweretambémcobraumataxamensalparausarseupróprionomededomínio--nãoémuitodinheiro,nototal,masissoprovavelmenteéalgoquevocêsóquerfazersevocêestárealmentecomprometido!

Onderegistrarumdomínio?Umdomínionormalcustamaisoumenos15dólaresporano.Existemdomíniosmaiscarosemaisbaratosdependendodoprovedor.Existemumasériedeempresasdasquaisvocêpodecomprarumdomínio:umasimplespesquisanogooglepodelistarumasériedelas.

OnossofavoritoéoIwantmyname(euqueromeunome).Elesanunciamseuserviçocomo"gestãodedomínioindolor",eele,realmente,éindolor.

Vocêtambémpodeobterdomíniosgratuitamente.dot.tkéumlugarparapegarum,masvocêdeveestarcientedequedomíniosgrátisàsvezesparecemmuitobaratos--seseusitevaiserparaumprofissionaldenegócios,vocêdevepensarempagarporumdomínio"correto"queterminaem.com.

ComoapontarseudomínionoPythonAnywhereSevocêpassouporiwantmyname.com,cliqueemdomíniosnomenueescolhaseudomíniorecém-adquirido.Emseguida,localizeecliquenolinkmanageDNSrecords:

Agoravocêprecisalocalizaresteformulário:

DjangoGirlsTutorial

131Domínio

Page 132: Djangogirls Tutorial Pt

Epreenchercomosseguintesdetalhes:-Hostname:www-tipo:CNAME-valor:seudomíniodePythonAnywhere(porexemplodjangogirls.pythonanywhere.com)-TTL:60

CliquenobotãoAdicionaresalveasmudançasnapartedebaixo.

NotaSevocêusouumprovedordedomíniodiferente,oUIexataparaencontraroseuDNS/configuraçõesdeCNAMEserádiferente,masseuobjetivoéomesmo:paraconfigurarumCNAMEqueapontaseunovodomínionoyourusername.pythonanywhere.com.

Podelevaralgunsminutosparaoseudomíniocomeçaratrabalhar,entãosejapaciente!

ConfigureodomínioatravésdeumwebappnaPythonAnywhere.VocêtambémprecisadizerPythonAnywherequevocêdesejausaroseudomíniopersonalizado.

VáparaapáginaPythonAnywherecontaseupgradesuaconta.Aopçãomaisbarata(umplanode"Hacker")ébomparacomeçar,vocêpodesempreatualizá-lomaistardequandovocêficarsuperfamosoetivermilhõesdeacessos.

Emseguida,vánaWebtabeanotealgumascoisas:

CopieocaminhoparaseuvirtualenvecoloqueemumlugarseguroCliqueparaseuarquivodeconfiguraçãodowsgi,copieoconteúdoecoleemumlugarseguro.

Emseguida,excluaseuantigowebapp.Nãosepreocupe,issonãovaiexcluirnadadoseucódigo,eleapenasirásedesligardodomínioyourusername.pythonanywhere.com.Emseguida,crieumnovoaplicativowebesigaestespassos:

DigiteseunomededomínionovoEscolha"manualconfiguration"EscolhaPython3.4Eéisso!

DjangoGirlsTutorial

132Domínio

Page 133: Djangogirls Tutorial Pt

Quandovocêtivervoltadoparaawebtab.

ColarocaminhovirtualenvquevocêsalvouantesClicarnoarquivodeconfiguraçãowsgiecolaroconteúdodoseuarquivodeconfiguraçãoantigo

Cliqueemreloadwebappevocêdeveencontrarseusitelivenonovodomínio!

Sevocêtiverqualquerproblema,cliquenolink"Enviarfeedback"nositePythonAnywhere,eumdosseusadministradoresamigáveisvaiestarláparaajudá-lo.

DjangoGirlsTutorial

133Domínio

Page 134: Djangogirls Tutorial Pt

Oquevemdepois?Parabéns!Vocêédemais.Estamosorgulhosos!<3

Oquefazeragora?

Façaumapausaerelaxe.Vocêacaboudefazeralgorealmentegrande.

Depoisdisso:

SigaDjangogirlsnoFacebookouTwitterparaficaratualizada

Vocêpoderecomendaroutrasfontes?

Sim!Primeiro,váemfrenteetentenossooutrolivro,chamadoDjangoGirlsTutorial:Extensions.

Depoisvocêpodetentarasfonteslistadasabaixo.Todaselassãorecomendadas!

Django'sofficialtutorialNewCodertutorialsCodeAcademyPythoncourseCodeAcademyHTML&CSScourseDjangoCarrotstutorialLearnPythonTheHardWaybookGettingStartedWithDjangovideolessonsTwoScoopsofDjango:BestPracticesforDjangobook

DjangoGirlsTutorial

134Oquevemdepois?