rolisz's site

Tutorial Camelot

Nu sunt Arthur sau Merlin, așa că nu voi vorbi despre orașul Camelot, ci despre frame­workul Python, care îi pretty much everything but the kitchen sink.

Cum tutorialul acesta este mai mult pentru colegii de grupă cu care lucrăm la proiect colectiv, voi presupune că este deja instalat Camelot.

Proiectul pe care îl vom crea este o mică chestie pe care eu vreau s-o fac de mai mult timp, și aceasta este opor­tu­ni­tatea perfectă: vom face un program cu care să pot urmări când se întâmplă anumite lucruri, în speranța ca mai încolo să pot extrage informații utile din când se întâmplă acele lucruri. Ce am de gând să măsor cu acest progrămel ar fi chestii gen viteza de creștere a unghiilor mele (peste 50 de ani o să scot un grafic frumos din asta :>:> ), când am dureri de cap (nu, mami, nu mă doare capul acuma), cât de des este control pe autobuz, etc. (Yes, I'm obsessed with data).

Mno, să începem. Se crează undeva un folder nou care va conține proiectul nostru. Se navighează în acel folder, de la linia de comandă și se execută următoarea comandă:

python -m camelot.bin.camelot_admin

Camelot
Initialization

Aici se com­pletează cu chestiile potrivite pentru noi, și când am terminat, ni se generază un schelet al pro­gra­mu­lui. Schelet funcțional!

Dacă rulăm (din IDE vă descurcați voi), de la linia de comandă cu:

python main.py

ar trebui să vedem următoare chestie:

Camelot
main

Deocamdată nu avem prea multe chestii, doar un schelet de bază, unde vom putea administra obiectele noastre.

Acum să creăm modelul pentru Stuff :D. În fișierul model.py, scrieți (nu copy-paste, că așa nu vă intră în „memoria” degetelor) ur­mă­toarele chestii:

    from sqlalchemy.schema import Column
    import sqlalchemy.types
    from camelot.admin.entity_admin import EntityAdmin
    from camelot.core.orm import Entity
    from sqlalchemy import Unicode, Date, Integer

    class Stuff(Entity):

        __tablename__ = 'stuff'

        id = Column(Integer, primary_key=True)
        name = Column(Unicode(60), nullable=False)

        def __unicode__(self):
        return self.name or 'Unknown'

        class Admin(EntityAdmin):
        verbose_name = 'Stuff'
        list_display = ['id', 'name']

Clasa nostră „Stuff” moștenește din Entity, care este clasa de bază a tuturor obiectelor care vor fi salvate în baza de date. Această clasă ne va oferi automat modalități de a salva și obține obiecte din baza de date, noi doar trebuie să zicem ce coloane avem, împreună cu tipul lor. Noi avem două coloane, un id care este cheia primară, și numele chestiei.

Funcția unicode spune ce ar trebui să pună Camelot dacă undeva trebuie să afișeze pur textual obiectul nostru. În acest caz, punem sau numele chestiei, sau „Unknown”.

Clasa interioară Admin, care moștenește din En­tityAd­min, este re­spon­s­abilă pentru ges­tionarea obiectelor noastre în interfața de ad­min­is­trare. ver­bose_­name stabilește numele care va fi afișat ca titlu, iar list_dis­play stabilește care coloane să fie afișate (în cazul nostru, prin pură co­in­ci­dență, toate).

Mai avem de făcut o mică modificare în fișierul ap­pli­ca­tion_ad­min.py. În funcția get_­sec­tions, la secțiunea 'My classes', la sfârșit, în items trebuie să adăugăm entitatea noastră: Stuff (care trebuie importată).

Acum dacă rulăm programul vedem că apare clasa noastră în coloana din stânga.

Stuff
administration

Făcând click pe Stuff, putem vedea obiectele pe care le-am adăugat deja, și dacă facem click pe butonul încercuit din imagine, ne apare fereastra de adăugare de noi obiecte.

stuff_add

Până acuma avem o entitate care ne zice ce s-a întâmplat, dar acum să adăugăm entitatea core­spun­ză­toare în­tâm­plării unei chestii. Aceasta va fi în relație many-to-one cu Stuff.

    from sqlalchemy.orm import relationship
    from sqlalchemy.schema import ForeignKey

    class Event( Entity ):

        __tablename__ = 'event'

        date = Column(Date())
        description = Column(Unicode(500))

        stuff_id = Column(Integer, ForeignKey('stuff.id'))
        stuff = relationship('Stuff')

        def __unicode__(self):
            return self.stuff or 'Unknown'

        class Admin(EntityAdmin):
            verbose_name = 'Event'
            list_display = ['id', 'stuff', 'date', 'description']

Apar două chestii noi aici: mai întâi declarăm stuff_id ca fiind un întreg care este FK pentru stuff, și apoi declarăm că avem un atribut stuff care este o relație cu „Stuff”. Mai trebuie să adaugăm analogul în Stuff, events = re­la­tion­ship('Event') și să adăugăm în ap­pli­ca­tion_ad­min.py, lângă Stuff și Event. Și gata. Avem tot ce ne trebuie.

Poate ați observat că nu am declarat niciun PK. Cheile primare nu trebuie create explicit, deoarece Camelot știe să creeze el automat un id de tip int dacă noi nu declarăm nimica.

Dacă vom încerca să adăugăm un eveniment nou, vom avea inclusiv au­to­com­plete pentru câmpul Stuff :>:>:> și datepicker pentru dată. Doar așa. Pentru că îi awesome Camelot.

event_add