Sunteți pe pagina 1din 74

UNIVERSITATEA “SPIRU HARET” BUCURESTI

FACULTATEA DE MATEMATICA SI INFORMATICA

LUCRARE DE LICENȚĂ

Coordonator Științific:
Student:
David Laurențiu-Georgian

2015
UNIVERSITATEA “SPIRU HARET” BUCURESTI
FACULTATEA DE MATEMATICA SI INFORMATICA

Coordonator Științific:
Student:
David Laurențiu-Georgian

2015
Cuprins

I INTRODUCERE.....................................................................................................................................4
1.1 Comertul Electronic.........................................................................................................................4
I.2 Beneficiile comertului electronic......................................................................................................7
I.3 Modele de afaceri.............................................................................................................................9
II ROLUL ȘI IMPORTANȚA INTERNETULUI ȘI A PAGINILOR WEB............................................13
II.1 Scurct Istoric.................................................................................................................................13
II.2 Prezentare si importanta................................................................................................................15
II.3 HTML. Prezentare.........................................................................................................................17
II.4 CSS. Prezentare.............................................................................................................................22
II.5 JavaScript. Prezentare...................................................................................................................25
II.5.1 Limbajul JavaScript................................................................................................................25
II.5.2 Prezentarea bibliotecii JQuery...............................................................................................31
II.6 Limbaje de scripting......................................................................................................................33
II.6.1 Python. Prezentare..................................................................................................................33
II.6.2 Frameworkul web Flask.........................................................................................................38
II.6.3 Administrarea bazelor de date cu SQLAlchemy....................................................................41
III. ARHITECTURA MAGAZINULUI WEB.........................................................................................44
III.1 Prezentarea magazinului..............................................................................................................44
III.2 Strucura backendului aplicației....................................................................................................54
III.3 Structura bazei de date.................................................................................................................64
IV. CONCLUZII......................................................................................................................................72
V. BIBLIOGRAFIE.................................................................................................................................74
DAVID LAURENȚIU INTRODUCERE

I INTRODUCERE

1.1 Comertul Electronic

Întreprinderile moderne sunt caracterizate printr-o cerere din ce in ce mai mare, prin existența
unei competiții la nivel mondial si prin sporirea permanentă a așteptărilor clienților. Ca să poată
raspunda acestor cerinte, întreprinderile de pe tot globul sunt în plin proces de tranformare
organizatională si a modului lor de funcționare. Comerțul electronic este o cale prin care se
facilitează si sprijină aceste schimbări, la scară globală.

Pentru unele firme, comert electronic înseamna orice tranzactie financiară care utilizează
tehnologia informatică. Pentru altele, notiunea de comert electronic acoperă circuitul complet de
vanzări - inclusiv marketingul si vanzarea propriuzisă.

Multi oameni consideră comertul electronic ca fiind orice tranzactie comercială condusă
electronic pentru cumpararea unor produse cum ar fi cărti, CD-uri, bilete de calatorie si altele.
Dar, comertul electronic are, in sens larg, un impact mult mai profund asupra evolutiei afacerilor
si cuprinde, in fapt, nu numai noile achiziții comerciale ci și totalitatea activităților care susțin
obiectivele de marketing ale unei firme și care pot include, spre exemplu, publicitate, vanzări,
plați, activitați post-vanzare, servicii catre clienți, etc.

Comertul electronic da posibilitatea firmelor sa devina mai eficiente si flexibile in modul intern
de funcționare, să conlucreze mai strâns cu furnizorii si sa devina mai atente față de nevoile si
asteptările clienților. Permite companiilor sa selecteze cei mai buni furnizori, indiferent de
localizarea lor geografica și să vandă unei piețe globale.

Această evoluție are un impact major asupra economiei, in ceea ce priveste crearea de noi
întreprinderi, diversificarea celor existente și, în special, asupra potențialului pieței forței de
muncă și a gradului de ocupare a acesteia in viitor. Industria comerțului electronic face, în
general, distincție între mai multe tipuri de tranzacții, unele active altele în așteptarea:

4
DAVID LAURENȚIU INTRODUCERE
- Business-to-Business (B-2-B sau BTB) cuprinde toate tranzacțiile ce se efectueaza intre doi sau
mai mulți parteneri de afaceri. Aceste tranzacții se bazeaza, de obicei, pe sisteme extranet, ceea
ce înseamna ca partenerii de afaceri acționeaza pe internet prin utilizarea de nume si parole
pentru paginile de web proprii. În termeni practici, în aceasta categorie de comerț electronic
poate fi orice firma care utilizeaza internetul pentru a comanda de la furnizori, pentru a primi
facturi si a efectua plați.

- Business-to-Consumer (B-2-C sau BTC) se refera la relațiile dintre comerciant si consumatorul


final, fiind considerat comerț electronic cu amănuntul. Aceasta categorie s-a extins foarte mult
datorita World Wide Web : exista acum mall-uri pe tot internetul care oferă toate tipurile de
bunuri de consum, de la prăjituri sau vinuri, la calculatoare si automobile.

- Business-to-Administration (B-2-A sau BTA) acopera toate tranzactiile dintre firme si autorități
administrative locale sau centrale. Spre exemplu, In Statele Unite ale Americii, licitațiile publice
lansate de guvern sunt publicate pe internet iar firmele pot răspunde pe cale electronică. In
momentul de fata, aceasta categorie de comert electronic este intr-o faza de dezvoltare primară,
dar se asteaptă o extindere rapidă, mai ales in contextul in care guvernele si alte autoritați
folosesc propriile metode de promovare a comerțului electronic. Aceasta categorie de e-
commerce ar putea, în viitor, sa fie utilizată și pentru plata TVA sau a impozitelor firmelor.

5
DAVID LAURENȚIU INTRODUCERE
Majoritatea afacerilor dezvoltate pe Internet, cu comerţ electronic, s-au dezvoltat în aria
Business-to-Business şi mai puţin Busines-to-Consumer. Business-to-Business(B2B) constă în
realizarea de tranzacţii între companii, transformând modul în care acestea lucrează între ele.
Iniţial transferul dintre companii se realiză prin intermediul unui sistem electronic de transfer
numit EDI(Electronic Data Interchange). Transferul electronic care are la bază sistemul EDI
transmitea datele conform unui format standard. Având în vedere faptul că documentele erau
aproximativ în acelaşi format, s-au putut realiza standarde după acestea şi a fost posibilă trecerea
lor în format electronic. Datorită faptului că reţelele EDI aveau un cost ridicat, multe companii
foloseau linii închiriate sau serviciile unor firme care ofereau conexiuni si servicii de transmisie
celor angajaţi în EDI (VAN – Value Added Network).

Folosirea unei astfel de metode pentru transferul datelor a prezentat şansa de a diminua
costurile pentru completarea formulalelor, listarea, trimiterea sau stocarea din nou într-un sistem
informatic odată ajunse la destinatar, precum şi erorile ce ar fi rezultat prin introducerea repetată
a datelor.

Odată cu apariţia Internetului s-a trecut la comerţul electronic bazat pe internet deoarece
folosirea acestuia este mai puţin costisitoare. Comerţul electronic bazat pe Internet a cunoscut
mai multe etape:

- etapa iniţială, etapă în care e-mail-ul a fost cea mai folosită tehnologie de transfer a datelor;

- etapa www, care a luat naştere odată cu apariţia primului browser web(Mosaic);

- etapa interactivă, când multe website-uri au introdus protocoale securizate de


comunicaţie, aplicații software pe partea de server şi/sau client, formulare, asigurând
interactivitatea client-furnizor;

- etapa maturizării web-ului, caracterizată de introducerea lui în cadrul intranet- ului


organizaţiei, utilizarea extranet-ului între organizaţii, utilizarea tehnologiei Python şi a
capabilităţilor multimedia ale Web-ului, care a devenit, astfel, un valoros canal de reclamă şi
publicitate(Piaţă Electronică).

6
DAVID LAURENȚIU INTRODUCERE

I.2 Beneficiile comertului electronic

În cazul comerţului electronic există avantaje atât pentru vânzator cât şi pentru
cumpărător. Avantajele pentru vânzător sunt următoarele:

- dispariţia limitelor geografice de vânzare;

- publicitatea online poate atinge publicul ţintă mai uşor;

- dezvoltarea de noi produse se poate realiza mai uşor în concordanţa cu cerinţele


consumatorului;

- adaptarea la schimbări este mai rapidă;

- disponibilitatea informaţiilor despre clienţi;

- economii la vânzarea produsului;

- îmbunătăţirea relaţiilor cu clienţii;

- reducerea erorilor prin automatizarea proceselor de plată;

- operabilitate 24 ore / zi, 7 zile pe saptamană.

Pentru cumpărător, comerţul electronic aduce următoarele avantaje:

- timpul redus de acces la produs;

7
DAVID LAURENȚIU INTRODUCERE

- identificarea mult mai uşoară de furnizori şi parteneri de afaceri;

- economii la cumpărarea prosusului;

- negocierea preţurilor se face mai uşor;

- scăderea costurilor tranzacţiilor prin creşterea vitezei de transfer a informaţiei;

- distribuirea online pentru produse digitale;

- lucrul la distanţă;

- accesul la produse/servicii din zone aflate la distanţă(exemplu: învăţământ la distanţă).

Dezavantaje:

- imposibilitatea de a realiza cu succes transferuri online a unor produse şi servicii (exemplu:


produse alimentare perisabile, bijuterii unicat, alte produse imposibil de inspectat la
distanţă, indiferent de tehnologiile curente);

- posibiliatea de non-profit în cazul anumitor produse;

- credibilitate scăzută;

- integrarea greoaie a bazelor de date şi a software-ului de procesare a tranzacţiilor


tradiţionale cu software pentru comerţ electronic (aceste servicii de integrare pot fi costisitoare).

Pe lângă problemele tehnologice şi legate de software, există şi alte obstacole:

- de natură culturală şi legală;

8
DAVID LAURENȚIU INTRODUCERE

- legate de securitatea comerţului electronic;

- legate de confidenţialitatea datelor (ce tranzacţii efectuează, ce site-uri vizitează, ce


preocupări are fiecare persoană etc.).

I.3 Modele de afaceri

Analizând aplicaţiile curente dezvoltate pe Internet, identificăm următoarele modele


de afaceri în comerţul electronic:

- magazin electronic (e-shop): un magazin electronic se implementează prin intermediul unui site
Web; acesta este gestionat de o companie, pentru marketingul şi vânzările propriilor produse şi
servicii. Minimal, conţine catalogul de produse sau servicii cu descrieri tehnice şi comerciale
pentru fiecare poziţie din catalog. Aceste descrieri sunt gestionate în general de un Sistem de
Gestiune al Bazelor de Date (SGBD). Sistemul de Gestiune al Bazelor de Date, se va ocupa cu
stocarea şi manipularea datelor şi cu oferirea posibilităţilor de acces la date. Varianta medie
conţine facilităţi pentru preluarea comenzilor (prin e-mail sau forme interactive pe care le vor
completa clienţii), iar varianta extinsă cuprinde şi posibilitatea efectuării on-line a plăţii (prin
cărţi de credit sau alte variante electronice).

- aprovizionarea electronică (eProcurement): pentru procurarea bunurilor şi serviciilor, marile


companii şi autorităţi publice organizează licitaţii. Prin publicarea pe Web a specificaţiilor
ofertei, scade atât timpul cât şi costul de transmisie, mărindu-se şi numărul de firme care iau
parte la licitaţie. Astfel, creşte concurenţa şi scade preţul.

- magazin electronic universal (eMall): ca şi în lumea reală, magazinul electronic universal este o
colecţie de magazine electronice, reunite sub o umbrelă comună şi care, în general, acceptă
metode de plată comune.

9
DAVID LAURENȚIU INTRODUCERE

- piaţa unui terţ (3rd party marketplace): se apelează la o interfaţă utilizator pentru catalogul de
produse al companiei, interfaţă ce aparţine unui terţ (în general, furnizor de servicii internet sau o
bancă). Această metodă are avantajul că interfaţa este unică pentru mai mulţi producători,
utilizatorii fiind familiarizaţi cu utilizarea ei

- comunităţi virtuale (virtual communities): valoarea cea mai importantă a unei comunităţi
virtuale este dată de către membrii săi (clienţi sau parteneri), care adaugă informaţii proprii peste
un mediu de bază furnizat de companie. Fiecare membru poate oferi spre vânzare produse sau
servicii sau poate adresa cereri de cumpărare a unor produse sau servicii. Calitatea de membru al
unei comunităţi virtuale presupune plata unei taxe.

- furnizor de servicii cu valoare adăugată pentru canalele de comerţ electronic (value chain
service provider): furnizorii de servicii sunt specializaţi pe funcţii specifice, cum ar fi asigurarea
logisticii, plata electronică sau expertiza în managementul producţiei şi a stocurilor. Plata acestor
servicii se face pe baza unor tarife sau a unei cote procentuale.

- platforme de colaborare: platformele de colaborare cuprind un set de instrumente şi un mediu


informaţional pentru colaborarea între companii. Acestea pot adresa funcţii specifice, cum ar fi
concepţia sau proiectarea în colaborare. Câştigurile provin din managementul platformei (taxa de
membru sau taxa de utilizare), şi din vânzări de instrumente specializate (pentru design,
workflow şi gestiunea de documente). Prin workflow se înţelege fluxul de documente, care
implică două entităţi: partea pasivă (documentele) şi partea activă (deplasarea acestor
documente).

- brokeraj de informaţii şi alte servicii: exemplele cuprind cataloage de clienţi clasificaţi pe


profil, vânzarea de oportunităţi de afaceri, consultanţă în domenii specializate. O categorie
specială o constituie serviciile de încredere furnizate de autorităţile de certificare sau de
notariatele electronice.

Un sistem electronic de plăţi se referă la totalitatea obiectelor care conlucrează pentru

10
DAVID LAURENȚIU INTRODUCERE
asigurarea plăţii tranzacţiilor ce se efectuează. Sunt implicate, în general, trei entităţi care
interacţionează: o banca B, un cumpărător C şi un vânzător V. Sistemul electronic de plăţi
conţine şi o mulţime de protocoale care permit cumpărătorului C să facă plăţi către vânzătorul V.
Sistemele electronice de plăţi pot fi privite într-o structură ierarhică pe nivele, derivate din
arhitectura sistemelor ISO-OSI .

Un Sistem Electronic de Plăţi (Fig. 1.3) este format din doua nivele:

- nivelul utilizator, care constituie nivelul ierarhic superior;

11
DAVID LAURENȚIU INTRODUCERE
- nivelul sistem, care constituie nivelul ierarhic inferior.

Nivelul utilizator constă din mulţimea utilizatorilor şi a tranzacţiilor care au loc între aceştia.
Utilizatorii sunt grupaţi după diverse roluri, după modul în care interacţionează în relaţiile de
afaceri dintre ei: cumpărătorul, vânzătorul, emitentul de bani electronici (banca), etc.

Nivelul sistem: constă din mulţimea entităţilor fizice şi a relaţiilor care se stabilesc între ele.
Entităţile pot juca unul dintre următoarele roluri: purtător de bani electronici sau registru de casă.

De-a lungul ultimilor ani, Comerțul Electronic a devenit o activitate comună pentru multe
companii. Unele dintre acestea au acceptat această provocare, fără a lua în considerare
schimbările culturale pe care le implică situaţia în cauză, precum şi infrastructura necesară pentru
a continua proiectul iniţial.

Pentru a începe dezvoltarea unei afaceri în lumea electronică, există unele puncte care trebuie
să fie acoperite. În primul rând este necesar să se stabilească o strategie de marketing, pentru a
crea un catalog de produse, pentru a defini costurile şi preţurile de vânzare, piaţa ţintă, preţurile
de transport şi de manipulare.

În prezent, majoritatea companiilor doresc să includă dezvoltarea E-Business. Această nouă


tehnologie, care se bazează pe Internet, este şi va rămâne pentru o lungă perioadă de timp o
variantă de dezvoltare a unei afaceri. Pentru a putea utiliza această tehnologie într-un mod
corespunzător, este necesar să se bazeze pe o bună organizare a informaţiilor şi proceselor.
Aceasta este o provocare, datorită faptului că cele mai multe companii nu au propriile lor sisteme
care să ofere sprijin pentru a rezolva nevoile specifice. Pentru a realiza o dezvoltare
corespunzătoare a acestui proiect este nevoie de o companie care are personal calificat.

12
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB

II ROLUL ȘI IMPORTANȚA INTERNETULUI ȘI A PAGINILOR WEB

II.1 Scurct Istoric

Internetul s-a născut la mijlocul anilor 60 în forma ARPAnet (Advanced Research Projects
Agency Net) - o reţea între mai multe computere din unele instituţii americane, ce lucrau pentru
ARPA, un departament de cercetare din cadrul Pentagonului. ARPA a fost pus în funcţiune ca
reacţie la succesul sovietic al lansării satelitului Sputnik în spaţiu în 1957. Unul din obiectivele
ARPAnet era crearea unei reţele, care să nu fie distrusă datorită atacurilor asupra sistemului.
Războiul Rece fiind la apogeu, scenariul unui dezastru era considerat fie lansarea unei bombe fie
un atac nuclear.

De aici a rezultat un proiect de reţea, unde reţeaua însăşi era permanent în pericol de atac. În
consecinţă:- doar un minimum de informaţii era cerut de la computerele client în reţea - oricând
transmisia de date întâlnea un obstacol, sau una dintre adrese era de negăsit, se găsea o altă cale
către adresa căutată.

Toate acestea au fost codificate într-un protocol care reglementa transmisia de date pe Internet.
În forma sa finală, acesta era TCP/IP (Transmission Control Protocol / Internet protocol), care
este şi acum baza Internetului. TCP/IP face posibil ca modele diferite de calculatoare, de
exemplu IBM compatibile sau Mac's, folosind sisteme diferite sisteme de operare, cum ar fi
UNIX, Windows, MacOS etc. Să se "înţeleagă" unele cu altele. În acest fel, internetul era şi este
cu adevărat o platformă independentă.

Internet-ul "civil" a început ca o reţea de patru computere între Universităţile din Utah, Santa
Barbara şi Los Angeles şi Institutul de Cercetare din Stanford. În curând, cercetători din alte
instituţii de stat au devenit interesaţi. Deoarece folosirea computerelor era costisitoare, ei au
văzut imediat avantajele folosirii în comun a unei reţele.

La sfârşitul anilor 60 şi începutul anilor 70, când Internetul număra în jur de 50 de computere,

13
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
s-au dezvoltat primele dintre servicii, folosite încă şi azi pentru transferul informaţiei:- File
Transfer Protocol pentru trimiterea şi regăsirea fişierelor - Telnet pentru accesarea şi folosirea
bazelor de date, a bibliotecilor şi a cataloagelor din toată lumea - E-Mail pentru trimiterea
mesajelor personale.

Internetul era în mod categoric în ascendenţă. Cu noi grupuri de utilizatori care se alăturau, în
următoarea decadă, Internetul a crescut la o reţea de 200 de computere. Partea militară era
organizată într-o reţea separată, Milnet.

În acelaşi timp, au apărut alte reţele, mai ales în sectorul academic. Importantă printre acestea
era (şi este) USENET sau Users' Network, care a început în 1979, când câteva computere UNIX
au fost conectate împreună.

USENET. În sute de grupuri de discuţii despre orice subiect imaginabil, oamenii făceau schimb
de noutăţi şi imagini, în ciuda distanţelor şi a hotarelor. Alte reţele s-au dezvoltat de-a lungul
USENETului. Toate formau baza unui spaţiu de comunicaţie radical democratic. De exemplu,
înaintea unei noi discuţii pe care grupul o începea, comunităţii Netului i se cerea un vot de
accept. Grupurile de discuţii joacă încă un rol mare pe Internet. Există mii şi zeci de mii în întreg
internetul.

Altă moştenire a USENET este "Netiquette", sau regulile de comportament pe Internet.

10 ani după ce USENET îşi începuse dezvoltarea, Internetul a crescut la 80.000 de computere.
A început să fie un factor de luat în considerare în politică. Şi curând, expresia "Information
SuperHighway" (autostrada informaţiei) a devenit uzuală. În această metaforă, Internetul era
văzut ca o importantă infrastructură pentru transportul unor bunuri vitale - informaţiile.

În anii 80 şi începutul anilor 90, când Internetul era folosit doar de un număr mic de cercetători,
arata mult diferit faţă de prezent. Principalele aplicaţii erau atunci poşta electronică şi grupurile
de discuţii (Newsgroups) plus diverse rutine de căutare şi mecanisme de transfer al fişierelor.
Aceasta era o lume UNIX, în care toate comunicaţiile existau doar ca text sau numere, şi liniile
de comandă trebuiau memorate şi tipărite.

Era destinat să fie o platformă internă de comunicaţii pentru cercetătorii din întreaga lume care
lucrau pentru CERN. Sarcina principală era să asigure un sistem care să facă legătura între

14
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
varietatea de platforme ale diverselor calculatoare.
Soluţia de bază era ideea de a face legătura între documente via "hipertext". Hipertext înseamnă,
a marca şirurile de text sau alte obiecte şi de a le lega cu alte obiecte, care ar putea fi din punct de
vedere fizic la mare distanţă de obiectul original. Când legătura este selectată, cineva poate "sări"
la documentul legat. În acest fel este posibil de a lega un număr nelimitat de documente între ele
într-o structură web ne-ierarhică. Pentru a putea deosebi aceste documente şi pentru a le regăsi,
fiecare are o adresă unică. Aceasta este Unique Resource Locator (URL). URL-urile constau într-
un protocol de transmitere (în cazul WWW-ului acesta este Hypertext Transfer Protocol - http),
urmat de www (în cele mai multe cazuri) şi de domeniu (de exemplu numele serverului şi
numele paginii).

Prima versiune a programelor pentru a naviga pe www, aşa numitele "browsere" urmau încă
tradiţia originală a internetului - erau numai text. De aceea, sistemul a rămas, în principiu,
neprietenos cu utilizatorii. În septembrie 1992 nu existau mai mult de 20 de servere web în
întreaga lume.

Schimbarea radicală s-a produs când NCSA (National Center for Supercomputing Applications)
din SUA a scos "Mosaic" - Browser în 1993, care era bazat pe o interfaţă grafică (Windows).
Enorma creştere a web-ului a început virtual, dintr-o dată: În iunie 1993, 130 servere Web erau
înregistrate, în 1994 erau deja 11.576 servere.

Dar web-ul nu a făcut doar să se dezvolte. De asemenea, posibilităţile de a prezenta datele au


crescut dramatic. Curând au apărut poze şi animaţii pe situri web, urmate de sunete . Doar un
mic pas mai era necesar pentru a aduce cataloage, directoare şi formulare de comandă pe situri
web. Astfel, câţiva ani mai târziu s-a născut E-Commerce.

II.2 Prezentare si importanta

În România, penetrarea internetului a crescut constant în ultimii ani, atingând 53% la nivel
naţional şi 63% la nivel urban în rândul persoanelor cu vârsta de peste 15 ani în aprilie 2013. În
acelaşi timp, apetitul românilor pentru tablete şi smartphone-uri este în continuă creştere.
Vânzările au cunoscut o importantă tendinţă ascendentă în ultimii ani, smartphone-urile

15
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
ajungând la o pondere de 25% din totalul pieţei de telefoane mobile în unităţi în 2012, iar
numărul de tablete vândute a crescut de aproape 5 ori în 2012 faţă de 2011.

Aceste evoluţii încep să îşi pună amprenta nu doar asupra stilului de viaţă al consumatorilor, ci
şi asupra comportamentului lor de cumpărare. Dacă până nu de mult magazinele şi mediile
tradiţionale de comunicare erau principalele surse de informare în vederea luării deciziei de
cumpărare, în prezent internetul este utilizat pe scară largă.

Un studiu desfăşurat de GfK România pe un eşantion reprezentativ pentru populaţia urbană


utilizatoare de Internet, cu vârste între 15 şi 45 de ani, relevă rolul important al internetului în
redefinirea comportamentului de cumpărare. 70% dintre cei chestionaţi declară că Internetul a
devenit un instrument de cumpărare foarte util, iar 44% menţionează că reţelele sociale au
devenit la fel de importante ca şi alte surse de informaţii pentru a face cele mai bune alegeri de
produse.

“Accesarea site-urilor de comparare a preţurilor, consultarea online a descrierilor detaliate ale


produselor şi a recenziilor altor cumpărători, schimbul de informaţii din reţelele sociale, toate
acestea sunt activităţi desfăşurate din ce în ce mai mult în vederea luării celei mai bune decizii de
cumpărare, care să aducă cea mai mare valoare cumpărătorului. Astfel, accesul la surse multiple
de informare ne transformă pe toţi în cumpărători mult mai implicaţi şi mai exigenţi, mai dificil
de mulţumit decât înainte”, spune Raluca Răschip, Consumer Goods & Retail Director GfK
România.

În afară de mediul online, treptat se dezvoltă şi alte medii de interacţiune, cum ar fi cel prin
intermediul smartphone-urilor. Dacă în momentul de faţă smartphone-ul este folosit cu precădere
pentru a compara preţuri (44% dintre deţinătorii care s-au informat online sau au cumpărat
online în ultimele 6 luni), pentru a căuta informaţii şi recenzii (42%) şi pentru a localiza
magazine (42%), şi alte tipuri de comportamente încep să apară: verificarea disponibilităţii unui
produs (31%) sau scanarea de coduri QR (22%).

16
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
În acest mediu în care cumpărătorul este mult mai conştient de instrumentele pe care le are la
îndemână şi mai implicat în procesul de cumpărare, utilizând tot mai multe pârghii pentru a
maximiza valoarea pe care o obţine, devine tot mai dificil pentru producători şi pentru retaileri să
păstreze un nivel de loialitate ridicat.

De aceea, cunoaşterea modului în care cumpărătorii se informează şi folosesc noile tehnologii,


a diversităţii stimulilor cu care aceştia intră în contact în procesul de cumpărare, devine din ce în
ce mai importantă pentru asigurarea succesului pe piaţă, nu doar pentru a răspunde nevoilor
actuale ale cumpărătorilor, ci şi pentru a anticipa nevoi viitoare într-un peisaj din ce în ce mai
digitalizat.

II.3 HTML. Prezentare

Unul din primele elemente fundamentale ale WWW (World Wide Web) este HTML (Hypertext
Markup Language), care descrie formatul primar in care documentele sunt distribuite si văzute
pe Web. Multe din trasaturile lui, cum ar fi independenta fata de platforma, structurarea
formatării si legaturile hypertext, fac din el un foarte bun format pentru documentele Internet si
Web.

Primele specificaţiile de baza ale Web-ului au fost HTML, HTTP si URL.

HTML a fost dezvoltat initial de Tim Berners-Lee la CERN in 1989. HTML a fost vazut ca o
posibilitate pentru fizicienii care utilizeaza computere diferite si schimbe între ei informaţie
utilizind Internetul. Erau prin urmare necesare citeva trasaturi: independenta de platforma,
posibilităţi hypertext si structurarea documentelor.Independenta de platforma înseamnă ca un
document poate fi afişat in mod asemănător de computere diferite, lucru vital pentru o audiență
atât de variată.

Hipertext înseamnă ca orice cuvânt, fraza, imagine sau alt element al documentului văzut de un
utilizator (client) poate face referinţa la un alt document, ceea ce uşurează mult navigarea intre

17
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
multiple documente sau chiar in interiorul aceluiași document. Structurarea riguroasa a
documentelor permite convertirea acestora dintr-un format in altul precum si interogarea unor
baze de date formate din aceste documente.

Standardul oficial HTML este World Wide Web Consortium (W3C), care este afiliat la Internet
Engineering Task Force (IETF). W3C a enunţat câteva versiuni ale specificaţiei HTML, printre
care si HTML 2.0, HTML 3.0, HTML 3.2, HTML 4.0 si, cel mai recent, HTML 4.01. In acelaşi
timp, autorii de browsere, cum ar fi Netscape si Microsoft, au dezvoltat adesea propriile
"extensii" HTML in afara procesului standard si le-au incorporat in browserele lor. In unele
cazuri, cum ar fi tagul Netscape , aceste extensii au devenit standarde de facto adoptate de autorii
de browsere.

HTML 2.0, elaborat in Iunie 1994, este standardul pe care ar trebui sa-l suporte toate
browserele curente -- inclusiv cele mod text. HTML 2.0 reflecta concepţia originala a HTML ca
un limbaj de marcare independent de obiectele existente pentru aşezarea lor in pagina, in loc de a
specifica exact cum ar trebui sa arate acestea. Dacă doriţi sa fiţi siguri ca toţi vizitatorii vor vedea
paginile aşa cum trebuie, folosiţi tagurile HTML 2.0.

Specificaţia HTML 3.0, Enunţata in 1995, a încercat sa dezvolte HTML 2.0 prin adăugarea
unor facilităţi precum tabelele si un mai mare control asupra textului din jurul imaginilor. Deşi
unele din noutăţile HTML 3.0 erau deja folosite de autorii de browsere, multe nu erau încă. In
unele cazuri, taguri asemănătoare implementate de autorii de browsere au devenit mai răspândite
decât tagurile "oficiale". Specificaţia HTML 3.0 acum a expirat, deci nu mai este un standard
oficial.

In Mai 1996, W3C a scos pe piaţa specificaţia HTML 3.2, care era proiectata sa reflecte si sa
standardizeze practicile acceptate la scara larga. Deci, HTML 3.2 include tagurile HTML 3.0 ce
erau adoptate de autorii de browsere ca Netscape si Microsoft plus extensii HTML răspândite. In
Bilanţul asupra HTML, W3C recomanda ca providerii de informaţii sa utilizeze specificaţia
HTML 3.2.Versiunile curente ale majorităţii browserelor ar trebui sa suporte toate, sau aproape

18
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
toate aceste taguri.

De asemenea exista extensii Netscape si Microsoft care nu fac parte din specificaţia HTML 3.2,
ori pentru ca sunt mai puţin utilizate, ori au fost omologate după apariţia HTML 3.2. Pentru ca
navigatorul Netscape a fost printre primele browsere care suporta anumite taguri HTML 3.0, iar
Netscape deţine in jur de 70% din piaţa de browsere, mulţi au crezut eronat ca toate extensiile
Netscape (incluzând taguri ca si facilitaţi ca ferestrele) fac parte din HTML 3.0 sau HTML 3.2.

Documentele HTML sunt documente in format ASCII si prin urmare pot fi create cu orice
editor de text. Au fost, însa, dezvoltate editoare specializate care permit editarea intr-un fel de
WYSIWYG deși nu se poate vorbi de WYSIWYG atâta vreme cat navigatoarele afişează același
document oarecum diferit, in functie de platforma pe care ruleaza. Au fost, de asemenea,
dezvoltate convertoare care permit formatarea HTML a documentelor generate (si formatate) cu
alte editoare. Evident conversiile nu pot pastra decât parțial formatările anterioare deoarece
limbajul HTML este înca incomplet.

Orice document HTML începe cu notaţia <html> si se termina cu notaţia </html>. Aceste
entitați se numesc in literatura de specialitate "TAG-uri". Prin convenţie, toate informaţiile
HTML încep cu o paranteză unghiulară deschisă " < " si se termină cu o paranteză unghiulară
închisa " > ".

Tag-urile între aceste paranteze transmit comenzi către browser pentru a afişa pagina într-un
anumit mod. Unele blocuri prezintă delimitator de sfârşit de bloc, în timp ce pentru alte blocuri
acest delimitator este opţional sau chiar interzis.

Intre cele doua marcaje <html> si </html> vom introduce doua secţiuni:

- secțiunea de antet <head>...</head>

- corpul documentului <body>...</body>. Blocul <body>...</body> cuprinde conţinutul

19
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
propriu-zis al paginii HTML, adică ceea ce va fi afişat in fereastra browser-ului.

Fig. 1.4 Structura unui document html.

Aplicând cele spuse mai sus vom ajunge la urmatorul rezultat:

<html>

<head><head>

<body></body>

</html>

Tagul <head> conține, de obicei, elemente precum tagul <title> - ce semnifică titlul paginii,

20
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
<script> - pentru a face referire la fisiere javascript – folosite pentru a da dinaminictate paginii,
<link> - folosit pentru a face referire la fisiere css ce contin informații despre aspectul
documentului.

In general, documentul va avea urmatoarea structura a elementelor conținute in tagul <head>:

<html>
<head>
<title> Titlul paginii </title>
<script src=”dinamism.js”></script>
<link rel=”stylesheet” type=”text./css” href=”stil.css >
</head>
<body>
</body>
</html>

Tagul <body> conține corpul documentului. Practic, in acest tag rezida toate elementele ce vor
fi afișate direct către utilizator. Pentru a structtura o pagina web cat mai eficient se folosește tagul
<div> ce marchează o porțiune din document ale cărei mărimi pot fi setate fie din interiorul
fișierului css sau aplicand atributele width si height acestui document.

Un exemplu practic de utilizare a tagului <div> este crearea unui meniu de navigare. Folosind
tagul <div> întregul meniu va fi privit ca o singura entitate. Aceasta este structura unui fisier
HTML ce conține un meniu de navigare minimalist implementat prin intermediul tagului <div>.

<!DOCTYPE html>
<html>
<head>
<title> Titlul paginii </title>
<script src=”dinamism.js”></script>

21
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
<link rel=”stylesheet” type=”text./css” href=”stil.css >
</head>
<body>
<div>
<ul>
<li> <a href=”sectiunea1.html”> Sectiunea 1 </a> </li>
<li> <a href=”sectiunea2.html”> Sectiunea 2 </a> </li>
<li> <a href=”sectiunea3.html”> Sectiunea 3 </a> </li>
</ul>
</div>
</body>
</html>

După cum puteți observa, am folosit tagul <ul> ce marcheaza o lista neordonată pentru a
introduce elementele meniului de navigare. Fiecare element din meniu de navigare este introdus
prin intermediul tagului <li> ce marcheaza un element al unei liste.
De asemenea, pentru a crea legaturi intre numele unei secțiuni si pagina acestei sectiuni am
folosit tagul <a> ce marcheaza un link spre o pagină, pentru a preciza pagina acționată de link
am folosit atributul href al acestui tag ce specifică resursa indicată de link.

II.4 CSS. Prezentare

CSS (Cascading Style Sheets) este un standard pentru formatarea elementelor unui document
HTML. Stilurile se pot atașa elementelor HTML prin intermediul unor fișiere externe sau în
cadrul documentului, prin elementul <style> și/sau atributul style.

Pentru a personaliza aspectul unui element dintr-un fisier HTML prin intermediu css este
necesara o modalitate de a face referire la acele elemente din interiorul unui fisier css. De obicei,
se folosesc atributede id si class ale unui tag html pentru a se face referire la el dintr-un fisier
css.

22
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB

În exemplul următor modficăm mărimea fontului unui paragraf si culoarea acestuia prin
intermediul unui fisser css.

#paragraf {
font-size: 23px;
font-color: blue;
}

Acesta este fișierul html asupra caruia aplicăm stilul definit in interiorul fișierului css.

<!DOCYPE html>
<html>
<head>
<link rel=”stylesheet” type=”text/css” href=”stil.css”>
</head>
<body>
<p id=”paragraf”>
Acesta este un paragraf.
</p>
</boody>
</html>

Este demn de precizat ca este nevoie sa precedem id-ul elementului cu un # atunci cand dorim sa
facem referire la un element dupa id-ul acestuia.

O alta caracteristică des folosita a fișierelor css este poziționarea unui element. Bazându-ne pe
același principiu expus în exemplul anterior putem poziționa un element dupa bunul plac
folosind atributele left, right, botton si top.

23
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB

In exemplul următor vom poziționa o imagine la 200px de partea din stanga a paginii si 200px
de partea din dreapta a paginii.

.imagine {
left: 200px;
top: 200px;
position: absolute;
}

Aceasta este structura fișierului html asupra căruia am aplicat stilurile definite in fisierul css
expus mai sus.

<!DOCTYPE html>
<html>
<head>
<link rel=”stylesheet” type=”text/css” href=”stil.css”>
</head>
<body>
<img src=”imagine.png” class=”imagine”>
</body>
</html>

Dupa cu observati, de aceasta data am folosit atributul class al tagului <img> pentru a face
referire la acesta din interiorul fișierului css. De asemenea, se poate observa ca în interiorul
fișierului css am prefixat clasa imaginii cu un punct, acesta fiind modul prin care selectam un
element in funcție de valoarea atributului class.

Deși nu foarte folosită în pactică, exista o a doua modalitate de a personaliza un fisier html prin
intermediul css fara a face referire la resurse externe. Pentru aceasta va trebui sa utilizam tagul

24
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
<style> din interiorul tagului <head>.

Acesta este modul in care putem scrie exemplul prezentat anterior intr-un singur fisier:

<!DOCTYPE html>
<html>
<head>
<style type=”text/css”>
.imagine {
left: 200px;
top: 200px;
position: absolute;
}
</style>
</head>
<body>
<img src=”imagine.png” class=”imagine”>
</body>
</html>

II.5 JavaScript. Prezentare

II.5.1 Limbajul JavaScript

JavaScript (JS) este un limbaj de programare orientat obiect bazat pe conceptul prototipurilor.
Este folosit mai ales pentru introducerea unor funcționalități în paginile web, codul Javascript
din aceste pagini fiind rulat de către browser. Limbajul este binecunoscut pentru folosirea sa în
construirea siturilor web, dar este folosit și pentru accesul la obiecte încastrate (embedded
objects) în alte aplicații. A fost dezvoltat inițial de către Brendan Eich de la Netscape

25
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
Communications Corporation sub numele de Mocha, apoi LiveScript, și denumit în final
JavaScript.

În ciuda numelui și a unor similarități în sintaxă, între JavaScript și limbajul Java nu există
nicio legătură. Ca și Java, JavaScript are o sintaxă apropiată de cea a limbajului C, dar are mai
multe în comun cu limbajul Self decât cu Java.

Codul scris in acest limbaj este introdus direct in interiorul fisierului HTML prin intermediul
tagului <script> sau se poate face referire la un fisier JavaScript prin intermediul atributului src
al tagului <script>. Prima variantă este cea mai des întalnită întrucât este ideala pentru scripturi
de dimensiuni mici, ce nu depasesc 200-250 de linii de cod. În mod normal, așa va arata un fisier
HTML ce conține si cod JavaScript:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type=”text/javascript”>
alert('alerta in javascript');
</script>
</body>
</html>

În exemplul de mai sus am folosit funcția alert pentru a demonstra modul de funcționare a unui
program simplu in JavaScript.

Definirea variabilelor

26
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB

In JavaScript, precum si în alte limbaje de scripting, nu este necesară declararea tipului de date
atunci cand definim o noua variabilă sau funcție. Totuși, definirea unei noi variabile se face
folosindu-ne de cuvântul cheie var, nu puteam pur și simplu sa folosim acea variabila fara sa o fi
declarat.
Exemplu de definire a variabilelor in limbajul JavaScript:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type=”text/javascript”>
var a = 1;
a = “string cu doua ghilimele”;
a = 'string cu apostroafe';
a = 2.3;
</script>
</body>
</html>

În exemplul de mai sus am creat o variabila a și i-am am atribuit pe rand 4 valori de tip: intreg,
string, string delimitat de apostroafe și număr real. Precum majoritatea limbajelor de scripting,
JavaScript, pune la dispoziie două modalități sintactice de reprezentare a stringurilor: forma ce
face uz de ghilimele și forma ce folosește apostroafele.

Structuri decizionale în limbajul JavaScript

27
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
Din punct de vedere al structurilor decizionale JavaScript se aseamnă foarte mult cu limbajele
C, C++ si Java. Exemplul urmator demostraza modul de folosire a celor mai frecvente structuri
decizionale, și anume: if/else/elseif și switch.

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type=”text/javascript”>
if(true) {
alert('ramura de adevar');
}
else if(undefined) {
alert('ramura elseif');
}
else {
alert('ramura else');
}

switch(variabila) {
case true:
alert('cazul de adevar');
break;
default:
alert('nicio ramura nu a fost acoperita');
}

</script>
</body>

28
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
</html>

În exemplul de mai sus am introdus o strucura decizională de tip if/elseif/else ce apeleaza


funcția alert, pasându-i ca și argumente stringurile: 'ramura de adevar', 'ramura elseif',
'ramura else', în funcție de ramura pe care se afla fluxul de execuție.

În cazul celui de al doilea exemplu, în care folosim structura switch, vom apela funcția alert
pasându-i ca și argument stringul 'cazul de adevar', atunci cand fluxul de executie se afla in
cazul in care valoarea variabilei variabila este true.

Structuri repetitive

Precum și in limbajul de programare C, limbajul JavaScript pune la dispozitie 3 structuri


repetitive principale: do/while, while, for.
În exemplul urmator voi prezenta fiecare din cele 3 structuri repetitive:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type=”text/javascript”>
do {
alert(i);
i++;
} while(i < 10);

while(i > 8) {
alert(i);

29
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
i--;
}

for(var i = 0; i < 20; i++) {


alert(i);
}
</script>
</body>
</html>

Bucla do/while va rula pana cand valoarea varieabilei i va fi mai mare decat 10, la fiecare iterație
se afișează valoarea variabilei i și se incrementează cu o unitate.

Bucla while va rula pană când valoarea ei va fi mai mica de 8, la fiecare iterație a buclei se va
afișa valoarea variabilei prin intermediul functiei alert, iar valoarea variabilei i va fi
decrementată cu o unitate.

Bucla for va rula până când valoarea variabilei i va fi mai mare de 20, la fiecare iterație a buclei
valoarea variabilei va fi incrementata cu o unitate, iar valoarea acesteia va fi afișată într-o căsuța
de dialog prin intermediul funcției alert.

Definirea functiilor

Limbajul JavaScript pune la dispoziție doua modalități de definire a funcțiilor, prima


asemănându-se foarte mult cu modul de definire a funcțiilor din limbajul php. Exemplul următor
ilustreaza modul de utilizare a celor doua modalități.

<!DOCTYPE html>

30
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
<html>
<head>
</head>
<body>
<script type=”text/javascript”>
function f() {
alert('f');
}
var g = function() {
alert('g');
}

</script>
</body>
</html>

Prima modalitate definește o funcție f ce va afișa o casuță de dialog cu textul f atunci cand este
apelată, iar a doua definește o variabila g caruia îi este atribuită valoarea unei funcții anonime ce
afișează o casuta de dialog cu textul g.

II.5.2 Prezentarea bibliotecii JQuery

Pentru a prelucra elementele DOM-ului prin intermediul JavaScript simplu vom întampina o
serie de dificultati, întrucat funcțiile folosite pentru realizarea acestor lucruri sunt implementate
diferit de producatorii de browsere, iar API-ul nativ pus la dispozitie de un browser pentru
efectuarea acestui lucru ofera o interfata neprietenoasa. Pentru a usura procesul de selectare si
modificare a elementelor DOM-ului vom folosi o biblioteca denumita JQuery.

Selectarea elementelor dupa id

31
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB

Pentru a modifica elementele unui document HTML este nevoie de o modalitate de a le accesa,
interfata pusă la dispoziție de JQuery se asemană foarte mult cu modul în care selectăm
elementele HTML din limbajul CSS. În exemplul urmator voi selecta tagul <p> cu id-ul
paragraf si voi adauga in interiorul acestuia textul text.

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type=”text/javascript”>
$(document).ready(function() {
$('#paragraf').append('text');
});
</script>
<div>
<p id=”paragraf”> </p>
</div>
</body>
</html>

Se observa apelul la metoda ready a documentului, scopul acestei acțiuni este de a executa cod
JavaScript decat dupa ce browserul a terminat de incărcat pagina complet. Folosind metoda
append aplicataă asupra elementului cu id-ul paragraf vom adauga textul text în interiorul
acestui element.

Tratarea evenimentelor

32
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
JQuery ne permite să legăm diferite evenimente de elemente din fisierul HTML. Spre
exemplu, atunci când se face click pe un buton va fi apelat evenimentul click. JQuery ne permite
să executam porțiuni de cod la executarea unui astfel de eveniment.

In exemplul de mai jos voi afisa o casuta de dialog de fiecare data cand se face click pe un
buton ce are atributul class egal cu “buton”.

<!DOCTYPE html>
<html>
<head></head>
<body>
<script type=”text/javascript”>
$('.buton').click(function() {
alert('ati apasat butonul');
});
</script>
<div>
<button type=”button” class=”buton”> Buton </button>
</div>
</body>
</html>

II.6 Limbaje de scripting

II.6.1 Python. Prezentare

Python este un limbaj de programare dinamic multi-paradigmă, creat în 1989 de programatorul


olandez Guido van Rossum. Van Rossum este și în ziua de astăzi un lider al comunității de
dezvoltatori de software care lucrează la perfecționarea limbajul Python și implementarea de

33
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
bază a acestuia, CPython, scrisă în C. Python este un limbaj multifuncțional folosit de exemplu
de către companii ca Google sau Yahoo pentru programarea aplicațiilor web, însă există și o serie
de aplicații științifice sau de divertisment programate parțial sau în întregime în Python.
Popularitatea în creștere, dar și puterea limbajului de programare Python au dus la adoptarea sa
ca limbaj principal de dezvoltare de către programatori specializați și chiar și la predarea
limbajului în unele medii universitare. Din aceleași motive, multe sisteme bazate pe Unix,
inclusiv Linux, BSD și Mac OS X includ din start interpretatorul CPython.

Python pune accentul pe curățenia și simplitatea codului, iar sintaxa sa le permite


dezvoltatorilor să exprime unele idei programatice într-o manieră mai clară și mai concisă decât
în alte limbaje de programare ca C. În ceea ce privește paradigma de programare, Python poate
servi ca limbaj pentru software de tipul object-oriented, dar permite și programarea imperativă,
funcțională sau procedurală. Sistemul de tipizare este dinamic iar administrarea memoriei
decurge automat prin intermediul unui serviciu „gunoier” (garbage collector). Alt avantaj al
limbajului este existența unei ample biblioteci standard de metode.

Implementarea de referință a Python este scrisă în C și poartă deci numele de CPython. Această
implementare este software liber și este administrată de fundația Python Software Foundation.

Tipizare

Limbajele dinamice sunt deseori caracterizate prin tipizare dinamică, sunt interpretate, au
management de memorie automatizat (garbage collecting) și au un nivel înalt de abstractizare.
Tipul variabilelor nu este fixat la momentul declarării acestora (de fapt, declararea variabilelor
nu este necesară ca în C), ci este determinat de interpretator după conținutul lor sau după
operațiile efectuate. Într-un asemenea caz se vorbește de tipizare dinamică.

Avantajul acestei metode de a lucra cu tipuri este că codul produs este mai clar și mai intuitiv. De
exemplu

34
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB

a = 10 # a va fi consider un număr întreg (integer)


b = 11.5 # b va fi considerat un număr rațional (double sau float)
c = "un rând de text" # c va fi considerat un șir (string)

În ciuda tipizării dinamice, Python este puternic tipizat, adică interpretatorul nu permite operații
cu obiecte de tip diferit dacă acestea nu sunt bine definite, cum ar fi operațiile de tip cast în C.
Există totuși unele excepții logice, cum ar fi în cazul numerelor întregi și celor raționale (float),
între care sunt permise operații ca adunarea sau împărțirea, tipul rezultatului ținând cont de
natura operației, cum se poate vedea mai jos

d = 10 + 11.5 # rezultatul va fi un număr rațional, 21.5


e = "o brioșă" + 4 # această comandă va genera o eroare.

Alt concept important în Python este cel al tipurilor mutabile și nemutabile. Așa cum implică
numele, datele cu un tip mutabil pot fi alterate după inițializare, în vreme ce la date nemutabile
lucrul acesta este imposibil. Luând ca exemplu o listă (mutabilă), constatăm că putem adăuga
elemente la listă sau le putem modifica fără probleme. În cazul unui șir de caractere (nemutabil),
acest lucru nu este permis:

lista_mea = ["măr", "pară"]


lista_mea.append("strugure") # adaugă la listă
print lista_mea[2] # afișază: strugure

șirul_meu = "varză"
șirul_meu[0] = "b" # schimbă cuvântul în "barză" -> Eroare

Structuri de date

Python oferă tipuri tradiționale de date, cum ar fi numărul întreg (integer, int) sau cel rațional

35
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
(float), dar introduce totodată și concepte noi.

De exemplu, un grad mare de flexibilitate îl oferă listele (tablourile) în Python. Acestea nu sunt
statice, ci pot conține orice tipuri de date (în cadrul aceleiași liste) și pot fi modificate pe loc
adăugând și eliminând elemente fără a declara sau utiliza funcții de manipulare a memoriei.

lista_mea = [10, "șir de caractere", variabilă, ["altă", "listă"], chiar_și_o_funcție]

Alte structuri de date sunt tuplurile/perechile (tuples) și dicționarele (dictionaries, mappings).


Tuplurile sunt liste care au un număr prestabilit de elemente, și nu pot fi modificate parțial.
Tuplurile pot fi utilizate în cazuri în care este nevoie de o anumită structură de date specializată,
de exemplu coordonate în spațiul cartezian. Dicționarele sunt liste neordonate în care fiecare
element are asociat o cheie, care poate fi număr sau șir de caractere. Dicționarele au foarte multe
aplicații, inclusiv crearea structurilor de tip hash-tables.

Stil

Python este un limbaj multi-paradigmă, concentrându-se asupra programării imperative,


orientate pe obiecte și funcționale, ceea ce permite o flexibilitate mai mare în scrierea aplicațiilor.
Din punctul de vedere al sintaxei, Python are un număr de contrucții și cuvinte cheie cunoscute
oricărui programator, dar prezintă și un concept unic: nivelul de indentare are semnificație
sintactică. Blocurile de cod sunt delimitate prin simplă indentare.

În C un astfel de blocuri sunt deseori desemnte prin acolade, {<cod>}, dar în Python nu este
nevoie de astfel de construcții. Nivelele de indentare îndeplinesc această funcție. Această
importanță a indentării este foarte suprinzătoare pentru mulți utilizatori noi ai limbajului Python,
chiar dacă sunt programatori cu experiență. Dar o astfel de utilizare a indentării permite codului
să fie mai ușor de citit și mai compact. Programatorii cu experiență vor indenta implicit codul
sursă, oricare ar fi limbajul, fiindcă astfel se permite structurarea codului sursă și evidențierea

36
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
funcționalității. Python face din această deprindere folositoare în acest sens o cerință strictă.

O impunere similară există și în limbajul de programare Java, care forțează programatorii să


delimiteze clasele în fișiere aparte, din motive de organizare și sporire a eficienței de scriere a
softului în echipe.

Biblioteci și Extindere

Includerea tuturor acestor structuri, precum și a funcțiilor ce permit manipularea și prelucrarea


lor, precum și multe alte biblioteci de funcții sunt prezente datorită conceptului “Batteries
Included”, ce poate fi explicat prin faptul că Guido van Rossum și comunitatea ce s-a format în
jurul limbajului cred că un limbaj de programare nu prezintă utilitate practică dacă nu are un set
de biblioteci importante pentru majoritatea dezvoltatorilor.

Din acest motiv Python include bibioteci pentru lucrul cu fișiere, arhive, fișiere XML și un set
de biblioteci pentru lucrul cu rețeaua și principalele protocoale de comunicare pe internet (HTTP,
Telnet, FTP). Un număr mare de platforme Web sunt construite cu Python. Abilitățile limbajului
ca limbaj pentru programarea CGI sunt în afara oricăror dubii. De exemplu YouTube, unul din
site-urile cu cea mai amplă cantitate de trafic din lume, este construit pe baza limbajului Python.

Totuși, Python permite extinderea funcționalității prin pachete adiționale programate de terți
care sunt axate pe o anumită funcționalitate. De pildă, pachetul wxPython conține metodele și
structurile necesare creării unei interfețe grafice.

Popularitatea limbajului este în creștere începând cu anul 2000, datorită faptului că Python
permite crearea mai rapidă a aplicațiilor care nu cer viteze înalte de procesare a datelor. De
asemenea este util ca limbaj de scriptare, utilizat în cadrul aplicațiilor scrise în alte limbaje.
Modulele (bibliotecile) Python pot fi de asemenea scrise în C, compilate și importate în Python
pentru a mări viteza de procesare.

37
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
II.6.2 Frameworkul web Flask

Spre deosebire de PHP, Python nu oferă suport direct pentru dezvoltarea aplicațiilor web,
pentru a dezvolta aplicații web in python este necesar un framework web ce va pune la
dispozitie toate funcțiile și dependințele necesare dezvoltării unei aplicații web.

Elementele de baza puse la dispozitie de Flask sunt: serverul web folosit pentru efectuarea
testelor, template engine-ul si o bibliotecă vasta de funcții uzuale în dezvoltarea unei aplicatii
web.

Structura unei aplicații web dezvoltate folosind Flask

Exemplul următor ilustreaza structura de baza a unei aplicații scrise in flask:

from flask import Flask


from flask import render_template

app = Flask(__name__)

@app.route('/index')
def index():
return render_template('index.html')

Dupa cum vedeți, este necesară importarea clasei Flask și a funcției render_template.
Variabila app va fi inițializată drep un obiect de tip Flask, acest obiect va conține toate datele ce
țin de configurarea aplicatiei.

38
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
Functia render_template va procesa templateul al cărui nume îi este pasat ca și argument si va
returna sub forma unui string conținutul acestuia. Motivul folosirii unei astfel de metode este
pentru a permite utilizarea structurilor de control ce permit crearea templateurilor într-un mod
dinamic.

Folosind decoratorul app.route înregistram funcția index drept un view. Astfel, funcția index
va fi apelată de fiecare dată cand un client solicită resursa /index.

De asemenea, Flask permite si introducerea variabilelor în URL si selectarea metodei aferente


unei rute. Exemplul urmator demonstreaza aceste lucruri:

from flask import Flask


from flask import render_template

app = Flask(__name__)

@app.route('/utilizator/<int:id>', methods=['GET', 'POST'])


def utilizator():
return render_template('pagina_utilizator.html')

Din exemplul prezentat mai sus putem observa ca ruta utilizator contine in URL o variabila de
tip integer ce semnifica id-ul utilizatorului. De asemenea, puteam observa ca metodele aferente
acestei rute sunt GET si POST. In mod standard, fiecare ruta permite accesul doar prin metoda
GET, folosirea metodei post este necesara decat dacă dorim sa procesăm un formular.

Prezentarea template engineului

Pentru a procesa templateurile intr-un mod dinamic este necesară folosirea unui template
engine ce implementeaza structuri de control de baza. Template engineul folosit de flask se

39
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
numeste Jinja2 și pune la dispoziție majoritatea structurilor de control întâlnite în limbajul
Python, asemănându-se foarte mult si din punct de vedere sintactic.

Exemplul următor ilustreaza un template ce genereaza in mod dinamic o listă HTML iterând
elementele dintr-o lista, pentru o mai buna întelegere am inclus și codul responsabil cu servirea
cererilor.

from flask import Flask


from flask import render_template

app = Flask(__name__)

@app.route('/lista')
lista = [1, 2, 3]
return render_template('lista.html', lista=lista)

Acesta este templateul

<!DOCTYPE html>
<html>
<head></head>
<body>
<ol>
{% for element in lista %}
<li> {{ element }} </li>
{% endfor %}
</ol>
</body>
</html>

40
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
Dupa cum se poate observa stuctura for folosită în template engine se aseamană foarte mult cu
cea folosită în limbajul Python. Demn de menționat este si faptul că strucurile de control sunt
scrise în interiorul elementelor {% și %}, iar atunci când dorim sa accesăm valoarea unui obiect
vom scrie numele acestuia intre elementele {{ și }}.

II.6.3 Administrarea bazelor de date cu SQLAlchemy

SQLAlchemy este un ORM(Object Relational Mapper) ce permite efectuarea de interogări


fara a mai scrie cod SQL. Folosind SQLAlchemy se va crea o relatie intre baza de date si modul
in care sunt reprezentate atributele clasei ce mosteneste clasa pusa la dispozitie de SQLAlchemy.

Crearea tabelelor în SQLAlchemy

În SQLAlchemy tabelele sunt reprezentate de clase ce moștenesc clasa db.Model.


Astfel, la rularea scriptului ce se ocupa de crearea bazei de date, SQLAlchemy, va crea tabelele
în funcție de clasele ce mostenesc clasa db.Model.
Pentru a defini câmpurile unui tabel vom inițializa fiecare atribut al clasei ce moștenește clasa
db.Model cu instanțe ale clasei db.Column.

Urmatorul exemplu ilustreaza conceptele explicate mai sus:

class Utilizator(db.Model)
id = db.Column(db.Integer, primary_key=True)
nume = db.Column(db.String, nullable=False)
prenume = db.Column(db.String, nullable=False)
parola = db.Column(db.Srtring, nullable=False)

41
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB
def __init__(self, nume, prenume, parola):
self.nume = nume
self.prenume = prenume
self.parola = parola

După cum se poate vedea, definim o clasa denumita Utilizator ce moștenește clasa db.Model.
Clasa Utilizator contine urmatoarele atribute: id – contine o instanta a clasei db.Column create
pentru un câmp de tip întreg ce este și cheie primară, nume – ce contine o instanță a clasei
db.Column inițializată pentru un camp de tip string a cărui valoare nu poate fi nulă, prenume -
ce conține o instanța a clasei db.Column inițializată pentru un camp de tip string ce nu poate
conține o valoare nulă, parola – conține o instanță a clasei db.Column inițializată pentru un
element de tip string ce nu poate conține o valoare nula.

Un alt avanatj al SQLAlchemy este faptul că nu constrânge utilizatorul la folosirea unui anumit
sistem de management al bazelor de date. In general, utilizatorii SQLAlchemy folosesc
PostgreSQL.

Executarea interogarilor

Avand in vedere faptul ca clasele ce moștenesc clasa db.Model sunt reprezentarile tabelelor din
baza de date, acestea conțin și metode speciale folosite pentru a efectua interogari.

Exemplul următor demonstreaza cele mai frecvent utilizate meode pentru efectuarea unei
interogări:

utilizatori = Utilizator.query.all()
george = Utilizator.query.filter_by(name='geroge').first()
utilizatorul1 = Utilizator.query.get(1)

42
DAVID LAURENȚIU ROLUL ȘI IMPORTANȚA
INTERNETULUI ȘI A
PAGINILORWEB

În primul exemplu atribuim variabilei utilizatori o lista ce va conție toate obiectele de tip
Utilizator din baza de date.

În al doilea exemplu atribuim variabilei george ca și valoare obiectul returnat de efectuarea unei
interogări după câmpul nume.

În al treilea exemplu atribuim vaiabilei utilizatorul1 valorea returnată de interogarea efectuata


cu scopul de a obține elementul cu id-ul 1.

Pentru a adăuga informații noi în baza de date va trebui sa adăugam obiectul modificat sau nou
creat in sesiunea pusa la dispozitie de SQLALchemy dupa ce am terminat de adaugat elementele
noi sau modificate în sesiune va trebui sa confirmăm schimbarea.

Exemplul următor ilustreaza introducerea unui nou utilizator în baza de date

utilizator = Utilizator(nume='David', prenume='laurentiu', parola='123444')


db.session.add(utilizator)
db.session.commit()

Apelul la metoda db.session.commit arată acordul nostru cu privire la introducerea noului


utilizator adaugat în sesiune în baza de date.

43
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB

III. ARHITECTURA MAGAZINULUI WEB

III.1 Prezentarea magazinului

Magazinul web creat in cadrul lucrării de licenta este unul ce se axeaza pe o gamă cat mai larga
de produse, oferind suport pentru o varietate de produse din diverse categorii. Pagina web este
împărțită in 3 zone: bara de navigare, zona de conținut si subsolul paginii.

Bara de navigare prezentată in figura 3.1 cuprinde: numele magazinului online – numele fiind
un link la pagina de index, butonul de acasă, butonul pentru pagina de contact, butonul ce
afișează meniul cu categoriile disponibile, casuța de căutare și butoanele de ieșire din cont și de
interogare a cosului.

Fig. 3.1 – Bara de navigare

Zona de conținut diferă în funcție de pagina pe care se afla utilizatorul. Spre exemplu, pe pagina
de cos se vor afisa elementele aflate in cos, valoarea acestora si meoda de plata.

44
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB

Fig. 3.2 – Conținutul paginii de coș

Zona de subsol conține o bară de navigare ce cuprinde numele creatorului magazinului web

Fig. 3.3 – Conținutul subsolului

In continuare, voi prezenta fiecare pagină din cadrul aplicației.

Pagina de index, conține un carusel cu imagini ale celor mai noi 3 produse, iar mai jos conține
informații detaliate despre produse, fiecare imagine este un link catre pagina produsului.

45
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB

Fig. 3.4 – Pagina de index

Pagina de contact, contine un formular de contact în care utilizatorul își va introduce datele de
contact si mesajul pe care dorește să-l transmită administratorului siteului. Dacă formularul
completat de utilizator a fost valid, utilizatorul va fi redirecționat pe o noua pagina in care ii este
confirmată trimiterea cu succes a emailului, iar un email cu mesajul utilizatorului va fi expediat
către administratori.

46
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB

Fig. 3.5 – Formularul de contact

Fig. 3.6 – Trimiterea cu succes a unui mesaj

47
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB

Fig. 3.7 – Recepționarea mesajului de catre administrator

Pagina de prosduse, va conține, în functie de categoria de produse selectată, toate produsele


disponibile in baza de date din acea categorie. Produsele vor fi afisate in panouri mici ce vor
conține: prețul, poza cu link spre pagina produsului și butonul de adăugare în coș.
Odată ce un produs a fost adăugat în coș. o casuță de dialog ce va confirma acest lucru va fi
afișată.

Fig. 3.8 – Adăugarea unui produs în coș

48
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB
Pagina de căutare, va conține toate rezultatele căutării efectuate prin intermediul căsuței de
căutare conținută în meniul de navigare. Rezultatele cautarii vor fi structurate astfel: poza
produsului cu link la pagina produsului, descrierea prosului, prețul acestuia si disponibilitatea
produsului.

Fig. 3.9 – Căutarea unui produs

Pagina de înregistrare, conține un formular cu datele pe care un utilizator trebuie sa le


completeze pentru a efectua cumpărături de pe această platforma. Dupa completarea datelor,
utilizatorului i se va trimite un email cu un cod de activare a contului, odata ce utilizatorul va
accesa linkul trimis prin email contul acestuia va fi activat.

49
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB

Fig. 3.10 – Pagina de înregistrare

Fig. 3.11 – Confirmarea trimiterii emailului ce conține codul de activare

50
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB

Fig.3.12 – Codul de activare trimis prin email

Fig. 3.13 – Activarea cu succes a contului

Pagina de autentificare, conține un formular cu 2 campuri: numele de utilizator si parola. Odata


trimis acest formular, utilizatorul va fi autentificat și va putea sa efectueze cumparaturi de pe
acest site.

51
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB

Fig. 3.14 – Autentificarea unui utilizator

Pagina de coș, va conține toate produsele aflate în coș la momentul accesării paginii și va oferi
utilizatorului posibilitatea să modifice cantitatea cumpărată din acel produs, să șteargă produsul,
să vizualizeze în timp real costul acelui produs și costul întregii tranzacții. După ce utilizatorul
și-a setat cantitatea dorită dintr-un anumit produs și a selectat și metoda de cumpărare, va trebui
să introducă datele de transport, iar un email cu factura va fi trimis.

Fig. 3.15 – Pagina de coș

52
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB

Fig. 3.16 – Introducerea datelor de transport

53
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB

Fig. 3.17 – Structura emailului ce conține factura

III.2 Strucura backendului aplicației

Pe partea de server, aplicația este împarțită în 21 de rute menite sa deserveasca fiecare dintre
paginile prezentate mai sus, atât si apelurile efectuate prin AJAX pentru a nu mai fi necesară
reâncarcarea paginii.

Demn de prezentat sunt urmatoarele rute:

Ruta pentru pagina de index, trimite uilizatorului pagina de index pasând funcției
render_template și o lista cu cele mai noi 3 produse in baza de date.

@app.route('/')
@app.route('/index')
def index():
promotionalProducts = Product.query.paginate(1, 3, False)
return render_template('index.html',
promotionalProducts=promotionalProducts)

Ruta pentru pagina de contact, îi va returna utilizatorului pagina de contact dacă acesta o
accesează pentru prima dată sau dacă formularul completat de acesta este unul invalid. Dacă
formularul completat de utilizator este unul valid, atunci se va realiza un apel la functia
sendMail pentru a-i trimite un email cu mesajul utilizatorului administratorului siteului. Funcția
sendMail este implementata in interiorul fișierului helper.py și este o interfață mult mai

54
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB
accesibilă a extensiei flask-mail ce necesită o cantitate mult mai mare de cod pentru transmiterea
unui mail. De asemenea, se poate observa ca funcția render_template este folosită pentru
generarea templaterurilor pentru mailuri, astfel putem scrie intr-un fisier HTML șablonul pentru
un email.

@app.route('/contact', methods=['GET', 'POST'])


def contact():
form = ContactForm()
if request.method == 'POST' and form.validate():
sendMail(subject='Conact',
sender=app.config['ADMINS'][0],
recipients=app.config['ADMINS'],
messageBody='-----',
messageHtmlBody=render_template('contact_mail.html',
email=form.email.data,
name=form.name.data,
message=form.message.data)
)
return render_template('message_send_successfully.html')

return render_template('contact.html', form=form)

Ruta pentru pagina de căutare, va returna templateul pentru pagina de cautare pasandu-i funcției
render_template ca și argument o lista de produse ce se potrivesc cu elementul cautat de
utilizator.

@app.route('/search', methods=['POST'])
def search():
products = Product.query.all()
productsToRender = []
for product in products:

55
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB
if request.form["search"] in product.name:
productsToRender.append(product)
return render_template('search_page.html', products=productsToRender)

Ruta pentru pagina de inregistrare va verifica validitatea formularului de înregistrare completat


de catre utilizator și, în funcție de validitatea acestuia, va trimite un email cu codul de activare
sau îl va atenționa pe utilizator să recompleteze corespunzător formularul.

@app.route('/singup', methods=['GET', 'POST'])


def singup():
form = SingupForm(request.form)

if request.method == 'POST' and form.validate():


newPendingUser = PendingUser(pendingId=str(uuid4()),
name=form.name.data,
username=form.username.data,
password=md5(form.password.data).hexdigest(),
email=form.email.data
)

db.session.add(newPendingUser)
db.session.commit()

mailUrl = generateUrl(
route=url_for('validateUser',
pendingUserId=newPendingUser.pendingId
),
hostname=request.host
)

sendMail(subject="Validation Mail",

56
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB
sender=app.config['ADMINS'][0],
recipients=[newPendingUser.email],
messageBody=render_template("confirmation_mail_body.html",
confirmationLink=mailUrl
),
messageHtmlBody=render_template(
"confirmation_mail_html_body.html",
confirmationLink=mailUrl
)
)

flash("User " + form.name.data + " was added")

return render_template("before_finish_singup.html",
email=form.email.data
)

flashErrors(form.errors, flash)
return render_template('singup.html',
form=form
)

Odată ce un utilizator a completat corect formularul de înscriere, acesta va fi adaugat intr-o


baza de date temporară pana ce linkul ce activare va fi accesat si va fi mutat in baza de date
primara. Ruta ce se ocupa de activarea conturilor va verifica validitatea codului de activare si il
va muta pe noul utilizator in baza de date primara in cazul in care codul de activare a fost valid.
În cazul în care codul de activare nu este valabil, utilizatorul va fi redirecționat spre o altă pagină
în care i se va spune acest lucru.

57
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB
@app.route('/validate/<pendingUserId>')
def validateUser(pendingUserId):
pendingUser = PendingUser.query.filter_by(pendingId=pendingUserId).first()
if pendingUser is None:
return render_template("invalid_activation_link.html")

user = User(name=pendingUser.name,
email=pendingUser.email,
password=pendingUser.password,
username=pendingUser.username
)

db.session.add(user)
db.session.delete(pendingUser)
db.session.commit()

return render_template("successfull_activation.html",
username=user.username
)

Ruta pentru pagina de login, va verifica validitatea formularului de login și, în funcție de acest
aspect, va decide daca utilizatorul va fi autentificat sau daca va fi redirecționat spre pagina de
autentificare – situație în care se ajunge în momentul completării incorecte a formularului de
autentificare.

@app.route('/login', methods=['GET', 'POST'])


def login():
form = LoginForm()
if request.method == "POST" and form.validate():
user = User.query.filter_by(username=form.username.data,

58
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB
password=md5(form.password.data).hexdigest()
).first()
if not user is None:
login_user(user)
flash('Te-ai logat cu succes')
return redirect(url_for('index'))
else:
flash("Numele de utilizator sau parola nu sunt corecte!")
flashErrors(form.errors, flash)
return render_template("login.html",
form=form )

Ruta pentru pagina de categorii, acesta rută va returna un template ce va conține toate produsele
dintr-o categorie suportată de magazin.

@app.route('/categories/<string:category>/<int:page>')
def categories(category, page):
products = Product.query.filter_by(category=category).paginate(page,
PRODUCTS_PER_PAGE, False
)

return render_template("products.html",
products=products
)

Ruta pentru pagina produsului, aceasta rută va reurna un template ce va contine toate datele
stocate in baza de date despre un anumit produs.

@app.route('/product_page/<int:productId>')
def productPage(productId=1):
product = Product.query.get(productId)

59
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB
return render_template("product_page.html",
product=product
)

Ruta pentru pagina de coș, aceasta rută va returna un template ce conține toate produsele
conținute în coș, dar și toate metodele de transport stocate în baza de date.

@app.route('/cart')
def cart():
form = AddressForm()
return render_template("products_in_cart.html",
cart=g.cart.getProductData(),
form=form
)

Ruta de updatare a coșului, este folosită pentru a adauga un produs nou în coș atunci când
apăsăm butonul de adăugare în coș. Această rută este folosită în apelurie AJAX pentru a nu mai
fi necesară reîncărcarea paginii atunci cand se va face click pe butonul de adaugare în coș.

@app.route('/update_cart', methods=['GET', 'POST'])


def updateCart():
g.cart.updateQuantity(int(request.form["id"]),
int(request.form["quantity"])
)
session["cart"] = g.cart.items
session.modified = True
app.save_session(session, make_response("dummy"))

product = Product.query.get(int(request.form["id"]))
return jsonify(total=product.price *

60
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB
int(request.form["quantity"])
)

Ruta pentru verificare a disponibilității unui produs, este folosită atunci cand utilizatorul
updateaza cantitatea unui produs pentru a verifica daca cantitatea introdusă de utilizator este în
concordanță cu valoarea stocului acelui produs.

@app.route('/check_stock', methods=['GET', 'POST'])


def checkStock():
product = Product.query.get(int(request.form["id"]))
return jsonify(stock=product.stock)

Ruta responsabila cu calcularea valorii coșului, este folosita pentru a spori securitatea și a evita
eventualele atacuri informatice realizate de utilizatorii rău voitori. Este mult mai sigur sa
calculăm valoarea coșului pe server decât să-i cerem browserului utilizatorului să o facă pentru
noi.

@app.route('/get_cart_total', methods=['GET', 'POST'])


def getCartTotal():
total=g.cart.getTotal()
return jsonify(total=round(total, 2))

Ruta pentru ștergerea unui produs din coș, folosită pentru a șterge un produs din cos prin
intermediul AJAX.

@app.route('/delete_from_cart', methods=['POST'])
def deleteFromCart():
g.cart.deleteFromCart(int(request.form['id']))
session["cart"] = g.cart.items
return jsonify(status="ok")

61
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB
Ruta pentru setarea metodei de transport, folosită pentru a selecta firma dorita pentru a transporta
produsul.

@app.route('/set_shipping_method', methods=['POST'])
def setShippingMethod():
for shippingMethod in g.shippingMethods:
if shippingMethod.name == request.form["name"]:
g.cart.updateShipping(shippingMethod.price)
session["shipping"]["price"] = g.cart.shipping
session["shipping"]["name"] = request.form["name"]
return jsonify(status="ok")
return jsonify(status="fail")

Ruta pentru obtinerea numelui firmei de transport, folosita pentru a menține valoarea firmei de
transport aleasă de utilizator de fiecare dată când acesta părăsește pagina.

@app.route('/get_shipping_method', methods=["POST"])
def getShippingMethod():
return jsonify(name=session["shipping"]["name"])

Ruta pentru plasare a unei comenzi, va verifica validitatea datelor de livrare completate în
formular de către utilizator, iar dacă acestea sunt valide va trimite un email cu factura
administratorului și unul clientului. În caz contrar il va avertiza pe utilizator de invaliditatea
datelor introduse de el.

@app.route('/place_order', methods=["POST"])
def placeOrder():
form = AddressForm(request.form)
if form.errors:
return jsonify(status='fail', errors=form.errors)

62
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB
for shippingMethod in g.shippingMethods:
if shippingMethod.name == request.form["shipping"]:
g.cart.updateShipping(shippingMethod.price)
userData = UserData(phone=form.phone.data,
email=form.email.data,
region=form.region.data,
city=form.city.data,
address=form.address.data)
userData.userId = g.user.id
db.session.add(userData)
db.session.commit()
# The third argument was an architerchtural mistake.
order = Order(g.cart.getTotal(), g.user.id, 1)
order.address = userData.id
db.session.add(order)
db.session.commit()

cart = []
for item in g.cart.items:
cart.append({
'quantity': g.cart.items[item]['quantity'],
'name': Product.query.get(item).name,
'price': g.cart.items[item]['price']
})

sendMail(subject='Factura',
sender=app.config['ADMINS'][0],
recipients=[form.email.data, app.config['ADMINS'][0]],
messageBody='----',
messageHtmlBody=render_template('bill.html',
cart=cart,

63
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB
name=g.user.name,
total=g.cart.getTotal(),
phone=form.phone.data,
region=form.region.data,
city=form.city.data,
address=form.address.data,
shipping=request.form['shipping'],
shippingCost=ShippingMethods.query.filter_by(
name=request.form['shipping']).first().price)
)

session["cart"] = {}

return jsonify(status="ok")

III.3 Structura bazei de date

Aplicația conține 11 clase ce moștenesc clasa db.Model și au drept corespondent un tabel în


baza de date.
În continuare, voi prezenta structura celor mai importante din aceste 11 clase.

Clasa utilizator, conține câmpuri pentru: nume, prenume, parolă, email, dar și un câmp userData
ce nu este direct reprezentat în baza de date, dar este specific SQLAlchemy. Scopul campului
userData din cadrul clasei User este de a accesa datele din tabelul UserData făra a mai fi nevoie
sa executăm o interogare.

class User(db.Model):
__tablename__ = 'user_table'

64
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB

id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String, nullable=False)
name = db.Column(db.String, nullable=False)
password = db.Column(db.String, nullable=False)
email = db.Column(db.String, nullable=False)
userData = db.relationship('UserData', backref='user', lazy='dynamic')

def is_authenticated(self):
return True

def is_active(self):
return True

def is_anoymous(self):
return False

def get_id(self):
return unicode(self.id)

def __init__(self, username, name, password, email):


self.username = username
self.name = name
self.password = password
# An user should have a primary email address.
self.email = email

def __repr__(self):
return "<User(%r, %r, %r)>" % (self.username, self.name, self.password)

65
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB
Meodele is_authenticated, is_active, is_anonymous si get_id sunt folosite cu scopul de face
clasa User compatibilă cu extensia flask-mail.

Clasa UserData, este folosită pentru a stoca date despre locația în care se va expedia produsul
unui utilizator. Motivul pentru care nu-l constrângem pe utilizator sa-și selecteze adresa de
transmitere a coletului de la început este pentru ca aceasta poate efectua o comanda de pe o
adresa diferita. Intre clasa User și clasa UserData este o relație de tip one-to-many, întrucat un
utilizator poate avea mai multe adrese.

class UserData(db.Model):
__tablename__ = 'userdata_table'

id = db.Column(db.Integer, primary_key=True)
phone = db.Column(db.String)
email = db.Column(db.String)
region = db.Column(db.String)
city = db.Column(db.String)
address = db.Column(db.String)
userId = db.Column(db.Integer, db.ForeignKey('user_table.id'))

def __init__(self, phone=None, email=None, region=None, city=None,


address=None):
self.phone = phone
self.email = email
self.region = region
self.city = city
self.address = address

def __repr__(self):
return "<UserData(%r, %r, %r, %r, %r)>" % (self.phone, self.email,
self.region, self.city, self.address)

66
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB

Clasa PendingUser, este folosită pentru a stoca temporar un utilizator până în momentul
accesării linkului de activare, moment în care utilizatorul va fi mutat în baza de date principală
permanent. Motivul folosirii acestui sistem de activare prin email este pentru a evita crearea de
conturi ce nu vor fi niciodată folosite.

class PendingUser(db.Model):
__tablename__ = 'pending_user_table'

id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String, nullable=False)
name = db.Column(db.String, nullable=False)
password = db.Column(db.String, nullable=False)
email = db.Column(db.String, nullable=False)
pendingId = db.Column(db.String, nullable=False, unique=True)
registrationDate = db.Column(db.DateTime, nullable=False)

def __init__(self, pendingId, username, name, password, email):


self.username = username
self.name = name
self.password = password
self.email = email
self.pendingId = pendingId
self.registrationDate = datetime.utcnow()

Clasa Product, este folosita cu scopul de reprezenta in baza de date un produs. Campurile:
comments, pictures și specifications nu vor fi reprezentate in baza de date. Scopul lor este să îi
elimine nevoia executării unei noi interogări.

class Product(db.Model):

67
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB
__tablename__ = 'product_table'

id = db.Column(db.Integer, primary_key=True)
category = db.Column(db.String, nullable=False)
description = db.Column(db.String, nullable=False)
name = db.Column(db.String, nullable=False)
price = db.Column(db.Float, nullable=False)
stock = db.Column(db.Integer, nullable=False)

comments = db.relationship('ProductComment', backref='product',


lazy='dynamic'
)
pictures = db.relationship('ProductPictures', backref='product',
lazy='dynamic'
)
specifications = db.relationship('ProductSpecifications',
backref='product',
lazy='dynamic'
)

def __init__(self, name, price, stock):


self.name = name
self.price = price
self.stock = stock

def __repr__(self):
return "<Product(%r, %r, %r)>" % (self.name, self.price, self.stock)

Clasa ProductPictures, este folosită pentru a reprezenta o poza a unui produs. Întrucât un
produs poate avea mai multe poze se creaza o relatie de tip one-to-many intre aceste 2 clase.

68
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB

class ProductPictures(db.Model):
__tablename__ = "product_pictures_table"

id = db.Column(db.Integer, primary_key=True)
link = db.Column(db.String, nullable=False)
date = db.Column(db.DateTime, nullable=False)
productId = db.Column(db.Integer, db.ForeignKey('product_table.id'))

def __init__(self, link, productId):


self.link = link
self.productId = productId
self.date = datetime.utcnow()

def __repr__(self):
return "<ProductPicures(%r)>" % self.link

Clasa ProductComment, este folosita pentru a reprezenta în baza de date un comentariu postat
de un utilizator la adresa unui produs. Ca și in cazul anterior, se creaza o relatia one-to-many
între clasele Product si ProductComment, întrucât un produs poate avea mai multe comentarii.

class ProductComment(db.Model):
__tablename__ = 'product_comments_table'
id = db.Column(db.Integer, primary_key=True)
comment = db.Column(db.String, nullable=False)
userId = db.Column(db.Integer, db.ForeignKey('user_table.id'))
productId = db.Column(db.Integer, db.ForeignKey('product_table.id'))

def __init__(self, comment, userId):


self.comment = comment
self.userId = userId

69
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB

def __repr__(self):
return "<ProductComment(%r)>" % self.comment

Clasa ProductSpecifications, este folosită pentru a stoca o specificație a unui produs. Întrucât
magazinul suporta diferite tipuri de produse nu se poate uniformiza într-un mod eficient modul în
care sunt reprezentate specificațiile unui produs. Din acest motiv am ales să introduc o nouă
tebela ce va conține câte o specificație, creandu-se, astfel, o relatie one-to-many între clasa
Product și ProductSpecifications.

class ProductSpecifications(db.Model):
__tablename__ = 'product_specification_table'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
data = db.Column(db.String, nullable=False)
productId = db.Column(db.Integer, db.ForeignKey('product_table.id'))

def __init__(self, productId, name, data):


self.productId = productId
self.name = name
self.data = data

def __repr__(self):
return "ProductSpecfication(%r)" % self.name

Pentru a adăuga un nou produs în baza de date va trebui sa instanțiem clasa Product și
ProductPictures – întrucât multe din funcționalitățile aplicației nu vor funcționa în lipsa unei
poze. Odata creată o nouă instanță a clasei Product este necesară adăugarea ei în baza de date.
Instata clasei ProductPictures poate fi adaugată in baza de date decât dupa ce a fost adaugată
cea a clasei Product întrucat este necesar id-ul produsului, iar id-ul este generat decât atunci

70
DAVID LAURENȚIU ARHITECTURA
MAGAZINULUI WEB
cand produsul este incărcat în baza de date.

Următorul exemplu dovedește conceptele ilustrate mai sus:

produs = Produs('cafea', 2.33, 23)

produs.descriere = 'cafea'
produs.category = 'cafea'

db.session.add(produs)
db.session.commit()

poza = ProductPictures('http://i.imgur.com/poza', produs.id)

db.session.add(poza)
db.session.commit()

71
IV. CONCLUZII

Această lucrare a prezentat procesul de dezvoltare a unei aplicații web de complexitate


medie, dar și uneltele moderne folosite pentru ducerea la bun sfarșit a unei astfel de aplicații.

Proiectul prezentat in acest document se diferențiază de celelalte din categoria sa prin folosirea
unei noi tehnologii, relativ noi pe partea de server – limbajul Python și biblioteca Flask.
Avantajul acestei diferențieri față de aplicatiile web clasice ce folosesc, de obicei, un limbaj
precum Php este ușurința în dezvoltare.
Dezavantajele acestei opțiuni sunt lipsa unor extensii ce ar putea să ajute programatorul în
procesul de devoltare al unui magazin web – a fost necesar să implementez această
funcționalitate de la zero, dar am compensat printr-un grad mai mare de flexibilitate – și faptul că
este mult mai dificilă găsirea unei companii de hosting cu un preț rezonabil care să suporte
tehnologiile folosite în acest proiect. Deși numărul companiilor ce oferă hosting pentru aplicații
ce folosesc Python și Flask este sesizabil mai mic, se compensează prin serviciile ireproșabile.
Astfel, companii precum Heroku sau Microsoft(cu platforma Windows Azure) oferă servicii
ideale pentru a găzdui această aplicație.

Flask este un framework web nou pe piață, fapt datorită caruia nu beneficiaza de mulțimea de
extensii pe care o are la dispoziție Django. Motivul pentru care am optat pentru Flask în
dezvoltarea acestei aplicații este flexibilitatea. Alegerea unui framework web precum Django ne-
ar fi impus un mod strict de dezvoltare ce ar fi făcut imposibilă implementarea anumitor
funcționalități.

În momentul de față, aplicația pune la dispoziție, cel puțin din punct de vedere al utilizatorului
de rand, toate specificațiile necesare pentru a-i conferi utilizatorului o experiență de utilizare
decenta. O funcționalitate ce ar fi sporit comunicarea cu utilizatorul ar fi fost implementarea unui
modul de chat, ce ne-ar fi permis să discutăm în timp real cu clienții noștri. Din punct de vedere
al administratorului magazinului, integrarea unui modul de adaugare a produselor ar fi ușurat

72
procesul, totuși diferența ar fi fost isesizabilă. În momentul de față, produsele se pot adauga prin
intermediul liniei de comandă sau prin intermediul unui sistem de management al bazelor de
date.

O funcționalitate pe care dorim să o adaugăm pe viitor este un sistem de validare a comenzilor


și a înregistrării utilizatorilor prin SMS - acest lucru ar duce la sporirea gradului de securitate.

73
V. BIBLIOGRAFIE

1. Python Cookbook, Brian K. Jones (2013), O'Reilly Media


2. Flask Web Development, Miguel Grinberg, (2014), O'Reilly Media
3. Head First HTML with CSS & XHTML, Eric Freeman, (2005), O'Reilly Media
4. Bootstrap, Jake Spurlock, (2013), O'Reilly Media
5. Essential SQLAlchemy , Rick Copeland, (2008), O'Reilly Media
6. PostgreSQL: Up and Running, Leo S, Hsu, (2012), O'Reilly Media
7. Functional JavaScript, Michael Fogus, (2013), O'Reilly Media
8. jQuery Cookbook, Cody Lindley, (2009), O'Reilly Media
9. Head First jQuery, Ronan Cranley, (2011), O'Reilly Media
10. Ajax: The Definitive Guide, Anthony T. (2011), O'Reilly Media

74

S-ar putea să vă placă și