Itererer raskt med Django & Heroku

Å starte en Internett-bedrift kan vise seg å være alvorlig komplisert. Selv om det på papir er enklere å lage en Internett-bedrift enn en murstein-en-murbruk, kan en gründer gå seg vill i mange muligheter. Noen av de vanligste fallgruvene en online entreprenør sitter fast i inkluderer:

  • Bygge for mye for tidlig: Miste tid og brenne penger å bygge et innviklet produkt. Få demotivated underveis, miste tro på produktet og forlate prosjektet.
  • Tro på for mye i ideen: Fester seg fast i den opprinnelige ideen og ikke itererer på den, selv om kundene ikke vises, ikke betaler eller ikke er fornøyd.
  • Sviktende å starte: Når noen begynner å bygge et webprosjekt, kan han / hun bli overveldet av de tilsynelatende uendelige beslutninger og valg som må gjøres. Hva hosting å bruke? Hvilken plattform? Hva WordPress tema? Hvordan bygge en high-converting destinasjonsside? Hvilket programmeringsspråk og hvilken database? Skal du bruke et webramme? Vanilla JavaScript eller jQuery for frontend? Kanskje et mer komplisert front-end rammeverk fordi prosjektet vil trenge en gang det er modent nok?
  • Unnlater å starte: Når du bygger et webprosjekt, kan du bli overveldet av tilbakemeldingen du får, selv om du har bestemt deg for teknologistakken din. Kontraintuitivt betraktes det som en feil å lytte til for mye tilbakemelding. Det kan være tilbakemeldinger fra folk som ikke ville bruke produktet ditt uansett. Folk har en tendens til å ha en mening om alt, selv om de ikke er helt kunnskapsrike i feltet.

Gitt mange måter man kan mislykkes langs veien, er det veldig viktig å:

  • Bygg så lite og så raskt som mulig, og vis det til folk som du anser som potensielle kunder: Minimer kostnader og krefter.
  • Sett det på nettet så snart som mulig: Få tilbakemelding fra personer på produktet, ikke på din abstrakte idé.
  • Gjør endringer raskt: Når du lærer hva kunden ønsker, er det avgjørende å være smidig og tjene dine første betalende kunder godt.

Her er hvor prototyping kommer på plass. En gründer burde kjøre seg og ikke kaste bort tid og ressurser. Å bygge så lite som mulig i begynnelsen kan vise seg en dyd. 

Det er mange tankeskoler om hva en prototype er og hvordan den skal opprettes. Noen sier at det bare skal være en destinasjonsside, andre at det burde være en fjernet versjon av sluttproduktet. Jeg er mer en fan av den andre. Å bruke bare en destinasjonsside kan føles scammy. Du kan heller ikke få tilbakemelding på hvordan du løser problemet, men bare om problemet er verdt å løse.

Her er verktøylengden til en smart prototyping online-entreprenør:

  • Front-End Frameworks: Bootstrap, Foundation, jQuery, Vue, etc. Ved å bruke en front-end-rammeverk, vil appene dine fungere på forskjellige skjermstørrelser og forskjellige nettlesere, med en anstendig design.
  • Back-End Framework: Django, Ruby on Rails, Laravel. Ved hjelp av back-end-rammer vil du lett kunne håndtere HTML-maler, HTTP-skjemaer, databasetilgang, nettadresseskjemaer, osv..
  • Platform-as-a-Service: Heroku, Google App Engine, AWS Elastisk Beanstalk. Å velge en PaaS kan frigjøre deg fra smerten ved å administrere servere, loggaggregasjon, oppetidskontroll, distribusjonsinfrastruktur og mer.

I denne opplæringen bygger vi et enkelt program i en ånd av rask prototyping. Vi bruker Django, Bootstrap CSS og Heroku. Fokuset vil være på back-end-delen i stedet for frontenden. 

Vi skal dra nytte av Heroku-plattformen for å sette noe på nettet tidlig og raskt distribuere nye funksjoner. Vi skal bruke Django til å bygge komplekse databasemodeller og funksjonalitet. Bootstrap CSS vil gi oss en fornuftig standardstil for våre sider. Nok snakk, la oss gå.

Hva vi bygger

Pass på at du setter deg ned for denne. Ideen vil slå dine sokker av. Her er banen: Ikke hater du bare hvordan du får alle disse rabattkoder, men du glemmer å bruke dem og de utløper? 

Ville det ikke være kult å lagre kodene et sted hvor du kan søke etter dem og også bli varslet når de skal utløpe? Jeg vet, god ide, ikke sant? Vel, legg kredittkortet ditt ned, du vil ikke investere i denne. Du skal bygge den.

Starter

I denne opplæringen skal jeg bruke Python 3. Hvis du bruker Python 2.7, bør endringene være ganske enkle. Jeg skal også anta at du er kjent med setuptools, Python virtualenvs og Git. En ting før du går fremover: sørg for at du har en GitHub og en Heroku-konto. For å bruke Heroku må du også installere Heroku CLI. 

La oss begynne med å lage en virtualenv:

$ mkvirtualenv coupy

Som du sikkert har funnet ut, er søknadsnavnet vårt Coupy. La oss bytte til den nye virtualenv, $ workon coupy, og installer Django: 

$ pip installere Django

Gå inn i GitHub-kontoen din og opprett et nytt prosjekt. Neste, la oss klone det prosjektet:

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

Det neste logiske trinnet er å skape et Django-prosjekt. For å distribuere et Django-prosjekt til Heroku, må vi følge noen retningslinjer. Heldigvis kan vi bruke en prosjektmal for det. Slik gjør du det:

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

Du må kanskje flytte rundt noen mapper. Forsikre deg om at mappens rotasjonsmappe ser slik ut:

. ├── Procfile ├── README.md ├── coupy │ ├── __init__.py │ ├── settings.py │ ├── statisk │ │ └── humans.txt │ ├── urls.py │ └ ─ - wsgi.py ├── manage.py ├── requirements.txt └── runtime.txt

La oss nå installere kravene som er oppgitt av malen:

$ pip installasjon -r krav.txt

Vi ønsker nå å skape de nyopprettede filene til GitHub:

$ git add. $ git commit -m "Init Django prosjekt" $ git push origin master

La oss se om det vi har gjort så langt, virker:

$ python manage.py runserver

Åpne nå et nettleservindu og gå til http: // localhost: 8000. Hvis alt er bra, bør du se den klassiske Django Welcome-siden. For å sikre at alt er bra fra Heroku perspektiv, kan vi også kjøre programmet slik:

$ heroku lokal web

For å bevise hvor raskt vi kan gå online, la oss gjøre vår første distribusjon til Heroku:

$ heroku login $ heroku create

Vi har nå opprettet et Heroku-program, men vi har ikke sendt noen kode til Heroku. Legg merke til at Heroku opprettet et brukervennlig app-id. Her er resultatet du bør få:

Oppretter app ... ferdig, ⬢  https: //.herokuapp.com/ | https://git.heroku.com/.git

Vi må nå knytte vår repo med den nyopprettede Heroku-appen:

$ heroku git: remote -a  $ git push heroku master $ heroku åpen

Fantastisk, du har nettopp distribuert en app til Heroku. Det gjør ikke mye, men du legger noe på nettet på rekordtid. Godt jobbet.

Sette opp databasen

Du vil nok aldri bygge en ikke-triviell webapp uten en database. Databasen er datalagringsdelen av webappen. Her er hvor webappa holder sin tilstand (minst det meste av det). Her holder vi brukerkontoene og påloggingsopplysningene og mye, mye mer. Heroku tilbyr en administrert PostgreSQL-tjeneste. 

Det er det vi skal bruke. Pass på at du har installert Postgres på maskinen din og opprett en databaseeksempel som skal brukes i vår søknad. Heroku trenger en miljøvariabel som skal settes inn for å kunne koble til databasetjenesten. Variabelen vi må sette er DATABASE_URL:

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

La oss nå fortelle Django å anvende migrasjonene og lage de nødvendige tabellene:

$ ./manage.py migrere

La oss lage en superbruker og logg inn på administrasjonsgrensesnittet på http: // localhost: 8000 / admin:

$ ./manage.py createsupperuser $ ./manage.py runserver

Vi kan se at tabellene faktisk har blitt opprettet. Heroku har allerede tilknyttet en databaseeksempel til appen din som standard. Du kan sørge for at det er tilfelle ved å sjekke inn Heroku HEROKU_APP_ID> Innstillinger> Konfig-variabler i din Heroku online konsoll. Du bør se her at DATABASE_URL er satt til en Heroku generert database adresse. 

Vi må nå kjøre flyttingene og lage superbrukerkommandoer på nettet. La oss se om alt fungerer som forventet:

$ heroku kjøre python manage.py migrere $ heroku kjøre python manage.py createsuperuser

Hvis alt gikk bra, hvis vi besøker https: //.herokuapp.com/admin/, Vi bør kunne logge inn med legitimasjonene vi nettopp har gitt.

Bruker autentisering

I denne delen skal vi initialisere en Django-app og bruke forhåndsdefinerte Django-komponenter for å opprette brukerautentiseringsfunksjonaliteten i appen vår.

$ ./manage.py startapp main

I den nye appen skal vi lage en urls.py fil:

fra django.conf.urls import url fra django.contrib.auth importvisninger som auth_views fra django.views.generic.base import RedirectView urlpatterns = [url ('^ $', RedirectView.as_view (url = 'logg inn'), navn = "index"), url (r '^ login $', auth_views.LoginView.as_view (), navn = "logg inn"), url (r '^ logout $', auth_views.LogoutView.as_view (), name = " Logg ut"), ] 

Her bruker vi tre generiske Django-visninger:

  • RedirectView: Siden grunnwebadressen til programmet ikke gjør noe, blir vi omdirigert til påloggingssiden.
  • LoginView: Django forhåndsdefinert visning som lager innloggingsskjemaet og implementerer brukerautentiseringsrutinen.
  • LogoutView: Django forhåndsdefinert visning som logger en bruker ut og omdirigerer til en bestemt side.

Legg til hoved- søknad til INSTALLED_APPS liste:

INSTALLED_APPS = ['django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', # Deaktiver Django egen statisk filhåndtering i tjeneste for WhiteNoise, for # større konsistens mellom gunicorn og './manage.py runserver'. Se: # http://whitenoise.evans.io/en/stable/django.html#using-whitenoise-in-development 'whitenoise.runserver_nostatic', 'django.contrib.staticfiles', 'main',]

Koble opp main.urls til roten URL-skjemaet:

fra django.conf.urls import url, inkludere fra django.contrib import admin urlpatterns = [url (r '^', inkluderer ('main.urls')), url (r 'admin /', admin.site.urls )]

For å vise skjemaene riktig, med stiler og klasser og alt, må vi installere Django-widget-tweaks:

$ pip installere django-widget-tweaks $ pip freeze> requirements.txt

Legg til Django-widget-tweaks til INSTALLED_APPS:

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

Vi legger nå disse to konfigene til settings.py:

  • LOGIN_REDIRECT_URL: Forteller Django hvor du skal omdirigere en bruker etter en vellykket autentisering.
  • LOGOUT_REDIRECT_URL: Forteller Django hvor han skal omdirigere brukeren etter at han / hun logger ut.
# settings.py LOGIN_REDIRECT_URL = 'dashbord' LOGOUT_REDIRECT_URL = 'logg inn'

La oss skrive en enkel mastermal base.html og a dashboard.html mal som strekker den ut. Vi kommer tilbake til oversikten en senere.

     % blokk tittel% % endblock%   
% blokkinnhold% % endblock%
% utvider 'base.html'% % blokk tittel% Dashboard % endblock% % blokk innhold% 

dashbord

% endblock%

Skriv visningen som gjør dashboard.html mal:

fra django.shortcuts import gjengi fra django.core.urlresolvers import reverse_lazy @login_required (login_url = reverse_lazy ('login')) def dashboard (forespørsel): return render (request, 'dashboard.html')

Vi er alle satt. Gå over til http: // localhost: 8000 / login / og test at autentisering fungerer. Deretter lagre fremgangen din:

$ git add. $ git commit -m "Logg inn / Logg ut / Dashboard visninger"

Opprett kupongmodellen

Nå har vi kommet til den viktigste delen av søknaden vår, og utformet kupongmodellen. Vi installerer django-modell-utils å legge til noen ekstra egenskaper til våre modeller.

$ pip installere django-modell-utils $ pip freeze> requirements.txt

Skrive den kupong modell:

fra model_utils.models importere TimeStampedModel, TimeFramedModel fra django.db importmodeller fra django.contrib.auth.models import Brukerklasse Kupong (TimeStampedModel, TimeFramedModel): owner = models.ForeignKey (Bruker) discount_code = models.CharField ("Rabattkode" , max_length = 100) website = models.URLField ("Website") description = models.TextField ("Kupongbeskrivelse")

De django-modell-utils modeller vi utvidet gjør oss i stand til å:

  • TimeStampedModel hjelper oss med å spore når modellen ble plassert i databasen via opprettet felt.
  • TimeFramedModel legger til start og slutt felt til vår modell. Vi bruker disse feltene for å holde oversikt over kupongens tilgjengelighet.

Fest modellen til administratoren:

fra django.contrib import admin fra .models import Kupong @ admin.register (Kupong) klasse CouponAdmin (admin.ModelAdmin): pass

Opprett og bruk migreringer:

$ ./manage.py makemigrations $ ./manage.py migrere

Lagre fremgang:

$ git add. $ git commit -m "Opprett kupong modell"

ModelForm for kupongopprettelse

En av de kule funksjonene i Django er evnen til å lage former fra modellklasser. Vi skal lage et slikt skjema som lar brukerne opprette kuponger. La oss lage en forms.py fil inne i hoved- applikasjon:

fra django.forms importerer ModelForm fra .models import Kupongklasse CouponForm (ModelForm): klasse Meta: modell = Kupong ekskluderer = ('eier') # Vi setter dette feltet selv

La oss legge til dette skjemaet til oversikten. Vi må endre både visningen og malen:

# views.py fra django.shortcuts import render, omdirigere fra django.core.urlresolvers importere reverse_lazy fra .forms import CouponForm @login_required (login_url = reverse_lazy ('login')) def dashboard (forespørsel): hvis request.method == ' POST ': form = CouponForm (request.POST) hvis form.is_valid (): coupon = form.save (commit = False) coupon.owner = request.user coupon.save () returnere omdirigering (' dashbord ') ellers: skjema = CouponForm () return render (forespørsel, 'dashboard.html', context = 'create_form': form)
% utvider 'base.html'% % last widget_tweaks% % blokk tittel% Dashboard % endblock% % blokk innhold% 

dashbord

% csrf_token%
% render_field create_form.discount_code placeholder = "Rabattkoden"%
% render_field create_form.website placeholder = "Nettsted"%
% render_field create_form.description placeholder = "Beskrivelse"%
% render_field create_form.start placeholder = "Tilgjengelig fra (MM / DD / ÅÅÅÅ)"%
% render_field create_form.end placeholder = "Utløper på (MM / DD / ÅÅÅÅ)"%
% endblock%

Vi har nå mulighet til å lage kuponger fra dashbordet. Gå og gi det en prøve. Vi har ingen måte å se kupongene i oversikten, men det kan vi gjøre i administrasjonspanelet. La oss lagre fremgangen:

$ git add. $ git commit -m "Kupong opprettelse skjema i dashbordet"

Utløper snart kuponger

En ting vi vil bli vist på dashbordet: Kuponger som utløper snart, for eksempel de som utløper denne uka.

Legg til django.contrib.humanize til INSTALLED_APPS å vise datoer i malene på en menneskelig måte.

La oss forbedre visningen slik at den henter de snart utgående kupongene og overfører dem til malekonteksten:

fra datetime import timedelta fra django.contrib.auth.decorators importere login_required fra django.shortcuts import render, omdirigere fra django.core.urlresolvers importere reverse_lazy fra django.utils importere tidszone fra .forms import CouponForm fra .models import Kupong @login_required (login_url = reverse_lazy ('login')) def dashboard (forespørsel): expiring_coupons = Coupon.objects.filter (end__gte = timezone.now (), end__lte = timezone.now () + timedelta (dager = 7)) hvis request.method = = 'POST': form = CouponForm (request.POST) hvis form.is_valid (): coupon = form.save (commit = False) coupon.owner = request.user coupon.save () returnere omdirigering ('dashbord') ellers : form = CouponForm () return render (forespørsel, 'dashboard.html', context = 'create_form': skjema, 'expiring_coupons': expiring_coupons)

La oss oppdatere malen slik at den viser de utgående kupongene på en tabellform. Vi legger også opprettingsskjemaet og tabellen i to separate kolonner med Bootstraps rutenett:

% utvider 'base.html'% % last widget_tweaks% % last humanize% % blokk tittel% Dashboard % endblock% % blokk innhold% 

dashbord

[Skjemakode]
% hvis expiring_coupons% % for kupong i expiring_coupons% % endfor%
Rabattkode nettsted Utløpsdato
Coupon.discount_code Coupon.website coupon.end | naturalday
% else%
Ingen kuponger utløper snart
% endif% % endblock%

Ser bra ut. Lagre fremgangen din:

$ git add. $ git commit -m "Implementering av utløper kupong liste"

Katalogvisning

La oss nå lære noen andre Django-snarveier for å lage en visning som viser listen over kuponger vi har tilgjengelig. Vi snakker om generiske visninger. Slik lager du raskt en Listevisning:

# views.py # ... fra django.views.generic.list importere ListView fra django.db.models importere Q klasse CouponListView (ListView): modell = Kupong def get_queryset (selv): retur Coupon.objects.filter (Q (end__gte = timezone.now ()) Q (end__isnull = True)). order_by ('end')

Slå nå visningen i URL-skjemaet ditt:

# main / urls.py fra django.conf.urls importere url fra django.contrib.auth importere visninger som auth_views fra django.views.generic.base import RedirectView fra .views import dashboard, CouponListView urlpatterns = [url ('^ $' , RedirectView.as_view (url = 'login'), navn = "indeks"), url (r '^ login / $', auth_views.LoginView.as_view (), navn = "logg inn"), url (r '^ logout / $ ', auth_views.LogoutView.as_view (), navn = "logout"), url (r' dashboard / $ ', dashbord, navn = "dashboard"), url (r' ^ catalog / $ ', CouponListView. as_view (template_name = 'catalogue.html'), navn = "katalog"),]

Lag malen catalogue.html:

% extends 'base.html'% % load humanize% % blokk tittel% Katalog % endblock% % blokk innhold% 

Katalog

% hvis objekt_list% % for kupong i object_list% % endfor%
Rabattkode nettsted Utløpsdato
Coupon.discount_code Coupon.website coupon.end | naturalday
% else%
Ingen kuponger ennå. Opprett din første her.
% endif% % endblock%

Siden vi har hektet alt opp, gå over til http: // localhost: 8000 / Katalog / for å se kupongkatalogen din.

Lagre fremgangen:

$ git add. $ git commit -m "Opprette katalogvisningen"

Dette er ganske nær en MVP. Jeg oppfordrer deg til å gjøre finjustering som å lage en navbar, logg inn / logg ut / registrer knapper, etc. Det viktigste er at du forstår prototypeprosessen og får produktet ditt der ute for at folk skal se det. Snakker av hvilket, er vårt produkt ikke på nett ennå. Vi presset ikke den nyeste versjonen til Heroku. La oss gjøre det, og hente telefonen og ringe investorene.

Konklusjon

Vi opprettet en enkel, men praktisk applikasjon. Vi har opprettet funksjoner raskt, og vi har distribuert dem på nettet, slik at våre potensielle kunder kan bruke dem og gi oss tilbakemelding. Det er bedre å vise folk enn å bare snakke om en ide. 

Her er noen konklusjoner vi kan tegne:

  • Å plukke de riktige verktøyene kan øke utviklingsprosessen betydelig.
  • Verktøyene som brukes til prototyping er ikke alltid det beste valget for mer modne prosjekter. Med dette i betraktning er det bedre å bruke mer smidige verktøy tidlig og lytte på dem, i stedet for å gå seg vill i små implementeringsdetaljer tidlig på.
  • Å dra fordel av en PaaS betyr at søknadene må respektere noen designmønstre. Vanligvis er disse mønstrene fornuftige, og de tvinger oss til å skrive enda bedre kode.
  • Django har mange snarveier som gjør livet enklere:
    • Django ORM hjelper med databasetilgang. Du trenger ikke å bekymre deg for å skrive riktig SQL og være ekstra forsiktig med syntaksfeil.
    • Migreringer hjelper oss med versjon og iterere på databaseskjemaet. Du trenger ikke å gå og skrive SQL for å lage tabeller eller legge til kolonner.
    • Django har en plugin-vennlig arkitektur. Vi kan installere apper som hjelper oss med å nå våre mål raskere.
    • Generiske visninger og modellformer kan injisere noen av de vanligste atferdene: notering modeller, skape modeller, autentisering, omdirigering, etc.
  • Når du starter, er det viktig å være slank og rask. Ikke kast bort tid, og ikke bruke penger.