Iterând rapid cu Django & Heroku

Lansarea unei afaceri online se poate dovedi a fi complicată. Deși pe hârtie este mai ușor să creezi o afacere online decât una de cărămidă și mortar, un antreprenor se poate pierde în multitudinea de opțiuni. Unele dintre cele mai frecvente capcane pe care un antreprenor online le-a blocat includ:

  • Construirea prea mult prea devreme: Pierdeți timp și ardeți bani construind un produs complex. Obțineți demotivarea pe parcurs, pierdeți încrederea în produs și abandonați proiectul.
  • Credeți prea mult în idee: Să rămânem la ideea originală și să nu iterăm, chiar dacă clienții nu se prezintă, nu plătesc sau nu sunt satisfăcuți.
  • Nu începe: Când cineva începe pe calea construirii unui proiect web, el / ea poate fi copleșit de deciziile și alegerile aparent infinite care trebuie făcute. Ce găzduire să utilizeze? Ce platformă? Ce temă WordPress? Cum se construiește o pagină de destinație cu conversie ridicată? Ce limbaj de programare și ce bază de date? Ar trebui să utilizați un cadru web? Vanilla JavaScript sau jQuery pentru partea din față? Poate un cadru mai complex de front-end, deoarece proiectul va avea nevoie de o dată când este destul de matur?
  • Lipsa lansării: Atunci când construiți un proiect web, chiar dacă ați decis cu privire la stiva dvs. de tehnologie, puteți fi copleșiți de feedback-ul pe care îl obțineți. În mod contrar, se consideră o greșeală să asculți prea mult feedback. Acesta poate fi feedbackul de la oameni care nu ar folosi produsul dvs. oricum. Oamenii tind să aibă o opinie despre tot, chiar dacă nu sunt complet informați în domeniu.

Având în vedere multitudinea de căi pe care le puteți face pe drum, este foarte important să:

  • Construiți cât mai puțin și cât mai repede posibil, arătând-o oamenilor pe care îi considerați potențiali clienți: Minimizați costurile și efortul.
  • Puneți-o online cât mai curând posibil: Obțineți feedback de la oameni despre produs, nu despre ideea dvs. abstractă.
  • Efectuați rapid modificări: Atunci când învățați ceea ce clientul dorește, este esențial să fii agil și să-i servți pe primii clienți plătitori.

Iată unde se face prototipul. Un antreprenor ar trebui să alerge mai puțin, fără a pierde timp și resurse. Construirea cât mai puțin posibilă la început poate dovedi o virtute. 

Există multe școli de gândire cu privire la ceea ce este un prototip și cum ar trebui să fie creat. Unii spun că ar trebui să fie doar o pagină de destinație, alții că ar trebui să fie o versiune dezbrăcată a produsului final. Sunt mai mult fan al celui de-al doilea. Folosind numai o pagină de destinație se poate simți înșelător. De asemenea, nu puteți obține feedback despre modul în care soluționați problema, ci mai degrabă numai dacă problema este în valoare de rezolvare.

Iată centura de instrumente a unui întreprinzător online inteligent de prototipuri:

  • Front-End Cadre: Bootstrap, Foundation, jQuery, Vue etc. Folosind un framework front-end, aplicațiile vor funcționa pe diferite dimensiuni ale ecranului și pe diferite browsere, cu un design decent.
  • Cadrele de back-end: Django, Ruby on Rails, Laravel. Utilizarea cadrelor back-end vă va ajuta să vă ocupați cu șabloanele HTML, formularele HTTP, accesul la baze de date, schemele de adrese URL etc..
  • Platforma-as-a-Service: Heroku, Google App Engine, AWS Elastic Beanstalk. Alegerea unui PaaS vă poate scuti de durerea gestionării serverelor, agregarea jurnalului, monitorizarea uptime, infrastructura de implementare și multe altele.

În acest tutorial, vom construi o aplicație simplă în spiritul prototipării rapide. Vom folosi Django, Bootstrap CSS și Heroku. Accentul va fi pus pe partea din spate, mai degrabă decât pe partea din față. 

Vom profita de platforma Heroku pentru a pune ceva online devreme și pentru a implementa rapid caracteristici noi. Vom folosi Django pentru a construi modele complexe de baze de date și funcționalitate. Bootstrap CSS ne va oferi un stil implicit sensibil pentru paginile noastre. Vorbește destul, hai să mergem.

Ce construim

Asigură-te că stai jos pentru asta. Ideea îți va lovi ciorapii. Iată pasul: Nu urați cum cum obțineți toate aceste coduri de discount, dar uitați să le utilizați și ei expiră? 

Nu ar fi bine să stocați codurile undeva unde le puteți căuta și, de asemenea, să fiți anunțat când urmează să expire? Știu, idee bună, nu? Puneți cartea dvs. de credit în jos, nu veți investi în acest. Voi o veți construi.

Noțiuni de bază

În acest tutorial, o să folosesc Python 3. Dacă utilizați Python 2.7, modificările ar trebui să fie destul de ușoare. De asemenea, voi presupune că sunteți familiarizat cu asta setuptools, Python virtualenvs și Git. Încă un lucru înainte de a merge mai departe: asigurați-vă că aveți un cont GitHub și un cont Heroku. Pentru a utiliza Heroku, trebuie să instalați și Heroku CLI. 

Să începem prin crearea unui virtuale:

$ mkvirtualenv coupy

După cum probabil ați dat seama, numele nostru de aplicație este Coupy. Să trecem la noul virtual, $ worky coupy, și instalați Django: 

$ pip instala Django

Accesați contul dvs. GitHub și creați un nou proiect. Apoi, să clonăm proiectul respectiv:

$ git clone https://github.com//.git $ cd 

Următorul pas logic este crearea unui proiect Django. Pentru a implementa un proiect Django către Heroku, trebuie să respectăm câteva linii directoare. Din fericire, putem folosi un șablon de proiect pentru asta. Iată cum puteți face acest lucru:

$ django-admin.py startproject --template = https: //github.com/heroku/heroku-django-template/archive/master.zip --name = Procfile coupy

S-ar putea să trebuiască să vă mișcați în jurul unor foldere. Asigurați-vă că dosarul rădăcină al depozitului dvs. arată astfel:

. ├── Procfile ├── README.md ├── coupy │ ├── __init__.py │ ├── settings.py │ ├── statică │ │ └── humans.txt │ ├── urls.py │ └ ─wsgi.py ├─────────────────────────────────────────────────────

Acum, instalați cerințele oferite de șablon:

$ pip instalare -r requirements.txt

Acum vrem să împingem fișierele nou create către GitHub:

$ git add. $ git commit -m "Proiectul Init Django" $ git push master de origine

Să vedem dacă ceea ce am făcut până acum funcționează:

$ server de administrare python manage.py

Deschideți acum o fereastră de browser și accesați http: // localhost: 8000. Dacă totul este bun, ar trebui să vedeți pagina clasică Django Welcome. Pentru a vă asigura că totul este bun din perspectiva lui Heroku, putem rula aplicația în felul următor:

$ heroku web local

Pentru a dovedi cât de repede putem merge online, să facem prima deplasare la Heroku:

$ heroku conectați $ heroku creați

Am creat acum o aplicație Heroku, dar nu am trimis niciun cod la Heroku. Observați că Heroku a creat un ID de aplicație prietenos. Iată rezultatele pe care ar trebui să le obțineți:

Crearea aplicației ... făcută, ⬢  https: //.herokuapp.com/ | https://git.heroku.com/.git

Acum trebuie să asociem repo-ul nostru cu aplicația nou creată Heroku:

$ heroku git: de la distanță -a  $ git împinge heroku master $ heroku deschis

Minunat, tocmai ai trimis o aplicație lui Heroku. Nu face prea mult, dar ai pus ceva online în timp record. Bună treabă.

Configurarea bazei de date

Probabil că nu veți crea niciodată o aplicație web non-trivială fără o bază de date. Baza de date este partea de stocare a datelor din aplicația web. Iată în cazul în care aplicația web își păstrează starea (cel puțin cea mai mare parte a acesteia). Aici păstrăm conturile de utilizator și detaliile de conectare și multe altele. Heroku oferă un serviciu PostgreSQL gestionat. 

Asta vom folosi. Asigurați-vă că ați instalat Postgres pe mașina dvs. și creați o instanță de bază de date care să fie utilizată în aplicația noastră. Heroku are nevoie de o variabilă de mediu care să fie setată astfel încât să se poată conecta la serviciul bazei de date. Variabila trebuie să setăm este DATABASE_URL:

$ export DATABASE_URL = "postgres: //:@localhost: 5432 /"

Să le spunem acum lui Django să aplice migrațiile și să creeze mesele necesare:

$ ./manage.py migrați

Să creați un superuser și să vă conectați la interfața de administrare la http: // localhost: 8000 / admin:

$ ./manage.py createsuperuser $ ./manage.py runserver

Putem vedea că mesele au fost într-adevăr create. Heroku a asociat deja o instanță de bază de date cu aplicația dvs. în mod implicit. Puteți să vă asigurați că este cazul verificând-o în Heroku HEROKU_APP_ID> Setări> Variabile configurare în consolă online Heroku. Ar trebui să vedeți aici că DATABASE_URL este setat la o adresă de bază de date generată de Heroku. 

Acum trebuie să rulați migrațiile și să creați comenzile super-utilizator online. Să vedem dacă funcționează așa cum era de așteptat:

$ heroku rulați python manage.py migrați $ heroku rulați python manage.py createsuperuser

Dacă totul a mers bine, dacă vom vizita https: //.herokuapp.com/admin/, ar trebui să ne putem conecta cu acreditările pe care tocmai le-am furnizat.

Autentificarea utilizatorului

În această secțiune, vom inițializa o aplicație Django și vom folosi componente predefinite Django pentru a crea funcția de autentificare a utilizatorilor în aplicația noastră.

$ ./manage.py startapp main

În interiorul noii aplicații, vom crea un a urls.py fişier:

din django.conf.urls importa url din opinii django.contrib.auth import auth_views din django.views.generic.base urlpatterns RedirectView import = [url ( '^ $', RedirectView.as_view (url = 'autentificare'), numele = "index"), URL-ul (R '^ autentificare $', auth_views.LoginView.as_view (), name = "conectare"), URL-ul (R '^ $ logout', auth_views.LogoutView.as_view (), name =“ logout "),] 

Aici folosim trei viziuni generice Django:

  • RedirectView: Deoarece adresa URL de bază a aplicației nu face nimic, redirecționăm către pagina de conectare.
  • LoginView: Vizualizare predefinită Django care creează formularul de autentificare și implementează rutina de autentificare a utilizatorilor.
  • LogoutView: Afișare predefinită Django care înregistrează un utilizator și redirecționează către o anumită pagină.

Adaugă principal aplicație la INSTALLED_APPS listă:

INSTALLED_APPS = [, 'django.contrib.auth' 'django.contrib.admin', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', proprii staticfiles # Dezactivarea lui Django de manipulare în favoarea WhiteNoise, pentru o consistență mai mare între gunicorn și "./manage.py runserver". A se vedea: # http://whitenoise.evans.io/en/stable/django.html#using-whitenoise-in-development 'whitenoise.runserver_nostatic', 'django.contrib.staticfiles', 'principal',]

Conectați-vă main.urls la schema de adrese URL a rădăcinilor:

din django.conf.urls import url, includ de la urlpatterns django.contrib import admin = [url (r '^', includ ( 'main.urls')), url (r '^ admin /', admin.site.urls ),]

Pentru a afișa formularele în mod corespunzător, cu stiluri și clase și tot ceea ce trebuie să instalăm django widget-trucurile:

$ pip instalează django-widget-tweaks $ pip freeze> requirements.txt

Adăuga django widget-trucurile la INSTALLED_APPS:

INSTALLED_APPS = [# ... 'principal', 'widget_tweaks',]

Acum adăugăm aceste două configuri settings.py:

  • LOGIN_REDIRECT_URL: Îi spune lui Django unde să redirecteze un utilizator după o autentificare reușită.
  • LOGOUT_REDIRECT_URL: Îi spune lui Django unde să redirecționeze utilizatorul după ce el / ea se loghează.
# settings.py LOGIN_REDIRECT_URL = 'tablou de bord' LOGOUT_REDIRECT_URL = 'login'

Să scriem un șablon de master simplu base.html și a dashboard.html șablon care o extinde. Ne vom întoarce la tabloul de bord mai târziu.

     % block title% % endblock%   
% conținutul blocului% % endblock%
% extinde 'base.html'% % block title% Tabloul de bord % endblock% % conținut bloc%% 

Tablou de bord

% endblock%

Scrieți vizualizarea care redă dashboard.html șablon:

de la django.shortcuts render import de la django.core.urlresolvers import reverse_lazy @login_required (login_url = reverse_lazy ('login')) tablou de bord def (cerere): return render (request, 'dashboard.html')

Suntem toți pregătiți. Treceți la http: // localhost: 8000 / autentificare / și testați că autentificarea funcționează. Apoi, salvați progresul:

$ git add. $ git commit -m "Logare / Deconectare / Vizualizări din tabloul de bord"

Creați modelul de cupon

Acum am ajuns la cea mai importantă parte a aplicației noastre, proiectând modelul Cuponului. Vom instala Django model-utils pentru a adăuga câteva proprietăți suplimentare modelelor noastre.

$ pip instalare django-model-utils $ pip freeze> requirements.txt

Scrie Cupon model:

de la model_utils.models import TimeStampedModel, TimeFramedModel de la modelele de import django.db de la importul django.contrib.auth.models Coupon de clasa utilizator (TimeStampedModel, TimeFramedModel): owner = models.ForeignKey (User) discount_code = models.CharField (" , max_length = 100) site = models.URLField ("Website") descriere = models.TextField ("Descriere cupon")

 Django model-utils modelele pe care le-am extins ne permit:

  • TimeStampedModel ne ajută să urmărim când modelul a fost plasat în baza de date, prin creată camp.
  • TimeFramedModel adaugă start și Sfârșit câmpuri la modelul nostru. Folosim aceste câmpuri pentru a urmări disponibilitatea cuponului.

Conectați modelul la admin:

din django.contrib import admin din .models import Coupon @ admin.register (Coupon) clasa CouponAdmin (admin.ModelAdmin): treci

Creați și aplicați migrații:

$ ./manage.py makemigrations $ ./manage.py migrați

Salvați progresul:

$ git add. $ git commit -m "Crearea modelului de cupon"

ModelForm pentru crearea de cupoane

Una dintre caracteristicile reci ale lui Django este abilitatea de a crea formulare din clasele de model. Vom crea o astfel de formă care permite utilizatorilor să creeze cupoane. Să creăm a forms.py fișier în interiorul principal cerere:

de la django.forms import ModelForm din .models import CouponForm (ModelForm): clasa Meta: model = Coupon exclude = ('owner',) #

Să adăugăm acest formular în tabloul de bord. Trebuie să schimbăm atât viziunea, cât și șablonul:

# views.py de la django.shortcuts import render, redirecționare de la django.core.urlresolvers import reverse_lazy de la .forms import CouponForm @login_required (login_url = reverse_lazy ('login')) def tablou de bord (request): if request.method == ' POST ': form = CouponForm (request.POST) dacă form.is_valid (): cupon = form.save (commit = False) cupon.owner = request.user coupon.save = CouponForm () retur render (cerere, 'dashboard.html', context = 'create_form': formular)
% extends 'base.html'% % încărcare widget_tweaks% % block title% Tabloul de bord % endblock% % conținut bloc%% 

Tablou de bord

% csrf_token%
% render_field create_form.discount_code placeholder = "Codul de reducere"%
% render_field create_form.website placeholder = "Site-ul"%
% render_field create_form.description placeholder = "Descriere"%
% render_field create_form.start placeholder = "Disponibil de la (MM / DD / AAAA)"%
% render_field create_form.end placeholder = "Expiră la (MM / DD / AAAA)"%
% endblock%

Acum avem o modalitate de a crea cupoane din tabloul de bord. Mergeți să încercați. Nu avem cum să vedem cupoanele din tabloul de bord, dar putem face acest lucru în panoul de administrare. Să salvăm progresul:

$ git add. $ git commit -m "Formularul de creare a cuponului în tabloul de bord"

Termenul de expirare a cupoanelor

Încă un lucru pe care vrem să îl afișăm în tabloul de bord: cupoane care expiră în curând, de exemplu, acelea care expiră în această săptămână.

Adăuga django.contrib.humanize la INSTALLED_APPS pentru a afișa datele în șabloane într-un mod prietenos cu oamenii.

Să îmbunătățim viziunea pentru a scoate cupoanele care expiră și le transmite în contextul șablonului:

de la datatime import timedelta de la django.contrib.auth.decorators import login_required de la django.shortcuts import render, redirecționare de la django.core.urlresolvers import reverse_lazy din django.utils import fus orar de la .forms import CouponForm din .models import Coupon @login_required (login_url = return_lazy ("login")) tablou de bord def (expiră): expiring_coupons = Coupon.objects.filter (end__gte = timezone.now (), end__lte = timezone.now () + timedelta (zile = = 'POST': form = CouponForm (request.POST) dacă form.is_valid (): coupon = form.save (commit = False) cupon.owner = request.user coupon.save : form = CouponForm () retur render (cerere, 'dashboard.html', context = 'create_form': formular, 'expiring_coupons': expiring_coupons)

Să actualizăm șablonul astfel încât să afișeze cupoanele care expiră în mod tabelar. De asemenea, vom pune formularul de creare și tabelul în două coloane separate utilizând sistemul de grilă Bootstrap:

% extends 'base.html'% % încărcare widget_tweaks% % load humanize% % block title% Tabloul de bord % endblock% % content block% 

Tablou de bord

[Codul formularului]
% dacă expiring_coupons% % pentru cupon în expiring_coupons% % endfor%
Cod de reducere website Data de expirare
Coupon.discount_code Coupon.website cupon.end | zi naturală
% else%
Nu există cupoane care expiră în curând
% endif% (% endblock%

Arata bine. Salvați progresul dvs.:

$ git add. $ git commit -m "Implementarea listei cu cupoane expirate"

Vizualizare catalog

Să învățăm acum câteva comenzi rapide Django pentru a crea o afișare care afișează lista de cupoane disponibile. Vorbim despre opinii generice. Iată cum să creați rapid o ListView:

# views.py # ... de la django.views.generic.list import ListView din django.db.models import Q class CouponListView (ListView): model = Cupon def get_queryset (self): return Coupon.objects.filter (Q (end__gte = time_replace ()) | Q (end__isnull = adevărat)) order_by ('- end')

Acum legați vizualizarea în schema de adrese URL:

# main / urls.py de la django.conf.urls import url din django.contrib.auth vizualizări de import ca auth_views de la django.views.generic.base import RedirectView din tabloul de bord de import .views, CouponListView urlpatterns = [url ('^ $' , RedirectView.as_view (url = 'login'), nume = "index"), url (r '^ login / $', auth_views.LoginView.as_view / $ ', url (r' ^ catalog / $ ', CouponListView), url (r' ^ dashboard / $ ', auth_views.LogoutView.as_view (), nume = "logout"). as_view (template_name = 'catalogue.html'), name = "catalog"),]

Creați șablonul catalogue.html:

% extinde 'base.html'% % load humanize% % bloc title% Catalog % endblock% % conținut bloc%% 

Catalog

% dacă object_list% % pentru cupon în object_list% % endfor%
Cod de reducere website Data de expirare
Coupon.discount_code Coupon.website cupon.end | zi naturală
% else%
Nu există încă cupoane. Creați-vă prima dvs. aici.
% endif% (% endblock%

De când am luat totul în cap, trebuia să mergem http: // localhost: 8000 / catalog / pentru a vedea catalogul de cupoane.

Salvați progresul:

$ git add. $ git commit -m "Crearea vizualizării catalogului"

Acest lucru este destul de aproape de un MVP. Vă încurajez să faceți o reglare fină cum ar fi crearea unui navigator, butoane de conectare / deconectare / înregistrare etc. Important este că înțelegeți procesul de prototipare și obținerea produsului dvs. acolo pentru ca oamenii să-l vadă. Vorbind despre care, produsul nostru nu este încă on-line. Nu am împins cea mai recentă versiune la Heroku. Să facem asta și apoi să ridicăm telefonul și să sunăm investitorii.

Concluzie

Am creat o aplicație simplă, dar practică. Am creat rapid funcțiile și le-am implementat online, astfel încât potențialii clienți să le poată folosi și să ne ofere feedback. Este mai bine să arăți oamenilor decât să vorbești despre o idee. 

Iată câteva concluzii pe care le putem trage:

  • Alegerea instrumentelor potrivite poate accelera semnificativ procesul de dezvoltare.
  • Instrumentele utilizate pentru prototipuri nu sunt întotdeauna cea mai bună alegere pentru proiecte mai mature. Ținând cont de acest lucru, este mai bine să folosiți mai devreme unelte mai agile și să le repetați mai degrabă decât să vă pierdeți din timp în detaliile de implementare minute.
  • Profitul unui PaaS înseamnă că aplicațiile trebuie să respecte câteva modele de design. De obicei, aceste modele au sens și ne obligă să scriem un cod mai bun.
  • Django are o mulțime de comenzi rapide care ne fac viața mai ușoară:
    • Django ORM ajută la accesarea bazei de date. Nu este nevoie să vă faceți griji cu privire la scrierea corectă a SQL-urilor și a fi foarte atenți la erorile de sintaxă.
    • Migrările ne ajută să executăm versiunea și să repetăm ​​schema bazei de date. Nu este nevoie să mergeți și să scrieți SQL pentru a crea tabele sau a adăuga coloane.
    • Django are o arhitectură prietenoasă pentru plugin-uri. Putem instala aplicații care ne ajută să ne atingem obiectivele mai repede.
    • Vizionările generice și formele de model pot injecta unele dintre cele mai comune comportamente: listarea modelelor, crearea de modele, autentificarea, redirecționarea etc..
  • La lansare, este important să fii ușor și rapid. Nu pierde timpul și nu cheltuiți bani.
Cod