Det främsta sättet att bemästra Django, eller vilken förmåga som helst, är att tillämpa teoretisk kunskap genom att skapa praktiska projekt.
Django framstår som det mest populära webbutvecklingsramverket för Python. Dess inbyggda funktioner och det enorma antalet tredjepartspaket har cementerat dess status som ett av de mest uppskattade ramverken globalt.
Det kännetecknas av snabbhet, pålitlighet och en uppsjö av integrerade funktioner. Ett exempel är det robusta autentiseringssystemet som gör att du kan fokusera på appens kärnfunktioner. Dessutom finns möjligheten att integrera externa paket för mer komplexa uppgifter, såsom Django-allauth för användarregistrering via sociala medier.
Men låt oss vara tydliga, Django är ett omfattande ramverk, vilket ibland kan göra det lite svårt att komma igång.
Därför kommer vi idag att bygga en fullt fungerande Django-applikation från grunden.
Efter denna genomgång kommer du att:
- Ha konstruerat en app för att förkorta webbadresser.
- Förstå Django MVT-modellen.
- Ha fått insikt i arbetsprocessen för att skapa ett projekt.
Förkunskaper
Följande förkunskaper är inte obligatoriska men underlättar förståelsen. Om du inte har erfarenhet av dessa, är det ingen fara. Det viktigaste är att börja.
- Grundläggande förståelse för UNIX-kommandon (ls, cd, rm, touch).
- Grundläggande förståelse för Python-klasser och funktioner.
- Python installerat på din dator (kanske självklart men det ska ändå nämnas).
- Det vore fördelaktigt om du har erfarenhet av att ha skapat något med Django tidigare.
All källkod kommer att vara tillgänglig på detta Github-arkiv.
Nu när grunderna är avklarade, låt oss gå in på detaljerna.
Projektbeskrivning
I den här genomgången kommer vi att utveckla en URL-förkortare. En URL-förkortare är en tjänst som konverterar en lång URL till en kortare, mer hanterbar länk.
Om du till exempel vill dela en länk på Twitter, där teckenantalet är begränsat, kan du använda en URL-förkortare.
Låt oss illustrera det grafiskt.
Som illustrationen visar tar URL-förkortaren emot en lång URL och returnerar en förkortad version. Det är precis det du kommer att skapa idag.
Genom detta projekt kommer du att öva på att använda MVT-modellen, lära dig grunderna i databasdesign med Django-modeller och utforska hur man presenterar data för användare via vyer, webbadresser och mallar.
Struktur för ett Django-projekt
En Django-webbplats består vanligtvis av ett huvudprojekt och flera separata applikationer. Varje applikation har en unik funktionalitet och kan fungera självständigt.
Tänk dig en komplex applikation som Stackoverflow. Dess funktioner kan delas in i två huvudområden.
- Användarhantering: Inloggning, Utloggning, Anseende, Behörigheter.
- Forum: Frågor, Svar, Taggar, Filter.
I enlighet med Djangos struktur skulle projektet heta StackOverflow och innehålla två huvudapplikationer: en för användare och en för forumet.
Varje applikation har sin egen oberoende funktionalitet. Detta innebär att båda innehåller all kod som behövs för att fungera korrekt.
Detta inkluderar modeller (databasstruktur), vyer (hantering av förfrågningar och svar), specifika URL-mönster och givetvis mallar och statiska filer (bilder, CSS, JavaScript). Därför kan Django-applikationer återanvändas eftersom de kan fungera på egen hand.
Kort sagt, ett projekt i Django avser en samling inställningar och applikationer som används för att bygga en webbapplikation. En Django-applikation är en komponent i ett projekt som är oberoende (innehåller allt som behövs) och är utformad för att utföra en specifik uppgift.
Skapa ett Django-projekt
I detta avsnitt kommer vi att sätta upp ett nytt Django-projekt. Vi kommer att använda olika verktyg, som en virtuell miljö för att hantera Python-beroenden, samt Djangos egna administrationsskript, Django-admin och manage.py.
Virtuell miljö
Det rekommenderas starkt att använda virtuella miljöer när du utvecklar appar med Django. Det är den effektivaste metoden för att hantera specifika beroenden och separera utvecklingspaket från globala paket.
Låt oss skapa en virtuell miljö med pythons inbyggda kommando.
Obs: Denna metod kräver Python 3.6 eller senare.
python -m venv .venv
Detta kommando använder antingen python -m eller python –mod för att exekvera en modul eller ett bibliotek som ett skript. I det här fallet anropar vi biblioteket venv och skapar en virtuell miljö med namnet .venv.
Kort och gott säger kommandot:
”Hej Python, kör det inbyggda biblioteket venv som ett skript och skapa en virtuell miljö med namnet .venv.”
Nu aktiverar vi den nyss skapade virtuella miljön med kommandot:
source .venv/bin/activate
För att verifiera att det inte finns några paket installerade i den nya virtuella miljön, kör:
pip freeze
Om den virtuella miljön aktiverades korrekt ska det inte visas någon utdata. Detta beror på att vi ännu inte har installerat något.
Dags för Django
För att skapa vår URL-förkortningsapplikation behöver vi först installera Django-paketet. Eftersom Django är ett tredjepartspaket, måste vi installera det med Pip (Pip Installs Packages).
$ pip install django Collecting django Downloading Django-3.2.1-py3-none-any.whl (7.9 MB) |████████████████████████████████| 7.9 MB 344 kB/s Collecting asgiref<4,>=3.3.2 Using cached asgiref-3.3.4-py3-none-any.whl (22 kB) Collecting sqlparse>=0.2.2 Using cached sqlparse-0.4.1-py3-none-any.whl (42 kB) Collecting pytz Using cached pytz-2021.1-py2.py3-none-any.whl (510 kB) Installing collected packages: asgiref, sqlparse, pytz, django Successfully installed asgiref-3.3.4 django-3.2.1 pytz-2021.1 sqlparse-0.4.1
Obs: Kom ihåg att $ inte är en del av kommandot utan bara din skalprompt.
Vi kan verifiera installationen genom att kontrollera vilka paket som är installerade i vår virtuella miljö.
$ pip freeze asgiref==3.3.4 Django==3.2.1 pytz==2021.1 sqlparse==0.4.1
Oroa dig inte om dina versionsnummer skiljer sig från mina. Så länge Django är på version 3.x, kan du fortsätta utan problem.
Starta ett Django-projekt
Nu när Django är installerat är det dags att skapa grundstrukturen för vår URL-förkortningswebbsida. Kommer du ihåg vad ett Django-projekt är? Låt oss skapa ett med följande kommando:
django-admin startproject config
För att förklara kommandot är django-admin ett kommandoradsverktyg som används för att utföra nödvändiga uppgifter för att skapa ett Django-projekt. ”startproject” är kommandot som körs av django-admin, och ”config” är namnet på projektet vi skapar.
Det är viktigt att notera att ”config” kan ersättas med valfritt namn. Jag använder ”config” av praktiska skäl, eftersom det underlättar att växla mellan projekt med en enhetlig namngivning. Använd gärna andra projektnamn om du vill.
Som du ser har nu en ”config”-mapp skapats som innehåller flera filer. Vi kommer att gå igenom projektets filstruktur senare. Låt oss först navigera till projektmappen och starta den lokala servern.
cd config/
Den viktigaste filen du kommer att använda är skriptet ”manage.py”. Det har liknande funktionalitet som django-admin, men den största fördelen är att du kan hantera projektinställningarna när du kör projektet.
Låt oss nu verifiera att allt fungerar som det ska.
python manage.py runserver
Skapa URL-förkortningsappen
Nu är det dags att skapa projektets huvudapplikation. Vi använder ”manage.py” för detta.
python manage.py startapp urlshortener
Detta skapar en Django-applikation med namnet ”urlshortener”. Om du använder ”tree”-kommandot får du en liknande struktur.
. ├── config │ ├── asgi.py │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── urlshortener ├── admin.py ├── apps.py ├── __init__.py ├── migrations │ └── __init__.py ├── models.py ├── tests.py └── views.py
Låt oss klargöra syftet med de olika filerna. ”config” är projektets namn, valt av konvention. Inuti ”config”-mappen finns ”settings.py”, där alla projektinställningar definieras. ”urls.py” innehåller webbadresskonfigurationen för projektet och definierar URL-vägarna för alla applikationer i projektet.
Du behöver inte oroa dig för ”asgi.py” och ”wsgi.py”. Dessa filer används för att konfigurera applikationen vid driftsättning.
”manage.py” är ett Python-skript som gör att du kan använda Django-admin kommandon.
Om du undersöker mappen ”urlshortener” som vi skapade, ser du en mapp med namnet ”migrations/” och andra viktiga filer för applikationens logik.
”apps.py” innehåller applikationskonfigurationen. Du behöver vanligtvis inte ändra den om du inte gör avancerade inställningar.
”admin.py” används för att registrera dina modeller så att de visas i Djangos administrationspanel.
”models.py” är central. Här definierar du modellerna, vilket (förenklat) definierar hur data lagras. Vi kommer att gå in på modeller senare.
”migrations/” är en mapp för Django-migreringar. Mer om detta senare.
”tests.py” är filen där tester lagras, men vi kommer inte att gå in på testning i den här genomgången.
”views.py” innehåller vyerna och definierar hur användaren interagerar med din applikation.
Installera en Django-app
Innan vi går vidare behöver vi öppna filen ”settings.py” och uppdatera variabeln INSTALLED_APPS med appen ”urlshortener”.
# Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # Custom apps 'urlshortener', ]
Detta är en standardprocedur när du skapar en applikation. Kom ihåg att lägga till den i projektinställningarna varje gång.
Förstå MVT-modellen
Mönstret Model, View, Template (MVT) är det designmönster som Django-utvecklare använder för att skapa webbapplikationer.
Det bygger på tre huvudkoncept: Modell (data), Vy (användarinteraktion med data) och Mall (hur användarna ser data).
Modeller är Python-klasser som definierar alla fält och beteenden för den data du vill lagra. Normalt refererar varje modell till en unik tabell i databasen.
Vyer är, i sin enklaste form, funktioner som tar en användarförfrågan och returnerar ett svar. Mellan dessa steg utförs affärslogiken. Affärslogik är hur data skapas, lagras och raderas.
Mallar är textdokument (vanligtvis HTML) som visas för användarna. Deras syfte är att presentera data på ett överskådligt sätt. Django har ett eget språk, Django mall-språk (DTL), som låter dig integrera Python-kod i textdokument.
Skapa förkortningsmodellen
Nu när vi har en grundläggande förståelse för MVT-modellen, låt oss börja skapa vår Django URL-förkortare.
Låt oss börja med att definiera förkortningsmodellen i ”models.py”.
''' Url shortener model ''' from django.db import models # Create your models here. class Shortener(models.Model): ''' Creates a short url based on the long one created -> Hour and date a shortener was created times_followed -> Times the shortened link has been followed long_url -> The original link short_url -> shortened link https://domain/(short_url) ''' created = models.DateTimeField(auto_now_add=True) times_followed = models.PositiveIntegerField(default=0) long_url = models.URLField() short_url = models.CharField(max_length=15, unique=True, blank=True) class Meta: ordering = ["-created"] def __str__(self): return f'{self.long_url} to {self.short_url}'
Detta är en omfattande klass med många detaljer, men vi kommer att gå igenom den steg för steg.
Förklaring av modellen
Först importerar vi ”models”-modulen, som innehåller all funktionalitet vi behöver för att skapa en Django-modell.
I modellen ”Shortener” ser vi att den utökar ”models.Model”. Alla modeller i en Django-applikation måste ärva från ”models.Model”-klassen.
Därefter definierar vi alla fält som modellen ska ha i databasen. Fältet ”created” lagrar datum och tid för när den förkortade länken skapas, vilket uppnås med ”DateTimeField”. Vi använder argumentet ”auto_now_add=True” för att säkerställa att fältet endast uppdateras när instansen skapas.
Fältet ”times_followed” räknar hur många gånger den förkortade webbadressen har använts. Vi använder ett ”PositiveIntegerField” med standardvärdet 0. Detta innebär att när en ny instans skapas fylls fältet med 0.
Fältet ”long_url” refererar till webbadressen som användaren anger. Det är ett ”URLField” eftersom vi vill att användaren ska ange en webbadress.
Det sista fältet, ”short_url”, har intressanta egenskaper. Vi anger att den får vara maximalt 15 tecken lång, måste vara unik och får vara tom. Det innebär att användaren inte behöver ange en egen förkortningskod.
Den inre klassen ”Meta” talar om hur klassen ska fungera. Vi konfigurerar här att de senaste objekten visas först när ”Shortener.objects.all()” anropas.
Metoden ”__str__” definierar hur modellen ska skrivas ut. Om vi har ett objekt med ”long_url = https://adminvista.com.com/” och en förkortad del ”123456” blir utskriften:
https://adminvista.com.com/ to 123456
Nu ska vi utforska ett sätt att spara korta länkar på ett slumpmässigt sätt.
Skapa förkortningsfunktionen
Vi skapar två anpassade funktioner. Den första genererar en slumpmässig kod, och den andra säkerställer att det inte skapas dubbletter i förkortningsmodellen. Skapa en fil ”utils.py” i applikationen ”urlshortener”.
touch utils.py
I den här filen använder vi funktionen ”choice” från den inbyggda modulen ”random” för att enkelt välja slumpmässiga tecken för koden.
''' Utilities for Shortener ''' from django.conf import settings from random import choice from string import ascii_letters, digits # Try to get the value from the settings module SIZE = getattr(settings, "MAXIMUM_URL_CHARS", 7) AVAIABLE_CHARS = ascii_letters + digits def create_random_code(chars=AVAIABLE_CHARS): """ Creates a random string with the predetermined size """ return "".join( [choice(chars) for _ in range(SIZE)] )
Som du ser returnerar den här funktionen en slumpmässig sträng med den längd som anges i inställningsfilen, eller 7 som standard. Vi använder ”getattr”-funktionen för att hämta en variabel från inställningsmodulen, utan att ett felmeddelande visas om variabeln inte finns.
Låt oss räkna lite. Med 7 positioner och upp till 62 tecken per position, får vi totalt permutationer som är:
Baserat på den enkla beräkningen kan den förkortade delen bestå av upp till 2,5 biljoner unika koder. Så risken för att få slut på unika förkortade webbadresser är minimal.
Trots det stora antalet permutationer finns det en liten risk för att skapa dubbletter. Eftersom ”shortened_url”-fältet måste vara unikt behöver vi följande funktion:
def create_shortened_url(model_instance): random_code = create_random_code() # Gets the model class model_class = model_instance.__class__ if model_class.objects.filter(short_url=random_code).exists(): # Run the function again return create_shortened_url(model_instance) return random_code
Här händer följande: Funktionen tar en instans av ”Shortener”-modellen som argument. Den genererar först en slumpmässig kod med ”create_random_code”. Därefter hämtar den modellklassen och kontrollerar om det redan finns ett objekt med samma ”short_url”. Om det gör det anropas funktionen igen, annars returneras ”random_code”.
Senare kommer vi att använda skalet för att undersöka denna funktion närmare.
Låt oss nu använda verktygsfunktionen för att generera slumpmässiga koder i förkortningsmodellen.
Ändra sparmetoden
I slutet av ”Shortener”-klassen ändrar vi metoden för att spara modellen. Sparmetoden anropas varje gång ett objekt sparas i databasen, vilket vi utnyttjar här.
# Import the function used to create random codes from .utils import create_shortened_url # At the end of the Shortener model def save(self, *args, **kwargs): # If the short url wasn't specified if not self.short_url: # We pass the model instance that is being saved self.short_url = create_shortened_url(self) super().save(*args, **kwargs)
Sparmetoden skrivs över, vilket innebär att vi lägger till ny funktionalitet till en befintlig överordnad metod. Vi säger till Django att varje gång ett ”Shortener”-objekt sparas och ”short_url” inte anges ska den fyllas i med en slumpmässig kod.
Kör migrering
Nu är det dags att skapa och tillämpa migreringarna för ”Shortener”-modellen. Kör följande kommandon i rotmappen för projektet:
$ python manage.py makemigrations Migrations for 'urlshortener': urlshortener/migrations/0001_initial.py - Create model Shortener $ python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions, urlshortener Running migrations: ...... # Apply the URL shortener migrations Applying urlshortener.0001_initial... OK
Du behöver inte bekymra dig om vad migreringar innebär just nu. När du kör dessa två kommandon skapar Django en ”db.sqlite”-databasfil baserat på de modeller du har definierat.
Låt oss skapa några objekt med hjälp av Djangos skal.
$ python manage.py shell >>> from urlshortener.models import Shortener >>> s = Shortener(long_url="https://adminvista.com.com") >>> s.short_url '' >>> s.save() >>> s.short_url 'kdWFVIc' >>> s.long_url 'https://adminvista.com.com' >>> print(s) https://adminvista.com.com to kdWFVIc
Så här fungerar förkortningsobjekten.
Skriva vyer
Som vi nämnde tidigare är en vy en enkel funktion som tar en förfrågan och returnerar ett svar. Låt oss skapa en ”Hello world”-vy.
Grundläggande mallrespons
Skapa en funktion ”home_view” i filen ”urlshortener/views.py”.
''' Shortener views ''' from django.shortcuts import render, get_object_or_404 # We will use it later from django.http import HttpResponse # Create your views here. def home_view(request): return HttpResponse("Hello world")
Detta returnerar ett enkelt ”Hello world”-meddelande. Vi ser senare hur detta visas i webbläsaren. Skapa nu en ”urls.py”-fil, där alla URL-mönster för appen kommer att finnas.
touch urls.py
Lägg till följande kod:
''' Urls for shortener app urlshortener/urls.py ''' from django.urls import path # Import the home view from .views import home_view appname = "shortener" urlpatterns = [ # Home view path("", home_view, name="home") ]
Variabeln ”appname” deklarerar namnutrymmet för ”urlshortener”-appen.
Vi importerar ”path”-funktionen, som returnerar ett element som läggs till i appens URL-mönster. Attributet ”name” är namnutrymmet för sökvägen, som kan användas i mallar vid behov.
Låt oss nu ändra de övergripande projektadresserna.
# config/urls.py from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), # Shortener Urls path('', include('urlshortener.urls')) ]
Låt oss starta servern igen.
python manage.py runserver
Om du startar servern visas ett enkelt ”Hello world”-meddelande. Det beror på att vi har inkluderat URL-mönster från URL-förkortningsappen i det övergripande projektet.
Detta är bara en startpunkt. Nu skapar vi ett formulär som gör det möjligt för användare att skapa egna förkortade webbadresser.
Skapa formulär
I Django är ett formulär en enkel klass som används för att samla in inmatning från användaren.
Vi kommer att skapa en fil ”forms.py”. Det är en konvention att lagra alla formulär för en applikation i den filen.
cd urlshortener/ touch forms.py
Inuti denna fil skapar vi en klass ”ShortenerForm” som ärver från ”ModelForm”.
''' Shortener Forms urlshortener/forms.py ''' from django import forms from .models import Shortener class ShortenerForm(forms.ModelForm): long_url = forms.URLField(widget=forms.URLInput( attrs={"class": "form-control form-control-lg", "placeholder": "Your URL to shorten"})) class Meta: model = Shortener fields = ('long_url',)
Det är ett modellformulär eftersom syftet är att skapa ett modellobjekt baserat på användarens inmatning. Vi använder även widgetargumentet för att ange attributet ”class” (klass i CSS, inte Python). Det beror på att vi kommer att använda Bootstrap för att styla appen senare.
Avsluta vyerna
Efter att ha byggt formulären är det dags att skapa den slutliga affärslogiken för applikationen.
Navigera till ”views.py” i ”shortener”-appen och ändra vyn ”home_view”. Du kan titta på Github-arkivet för en överblick av projektstrukturen.
Det finns två vyer för URL-förkortningsappen:
- Hemvyn: Visar förkortningsformuläret och den nya URL:en om formuläret har skickats.
- Omdirigeringsvyn: Omdirigerar till den långa webbadressen och ökar antalet ”times followed”.
Vi börjar med hemvyn, som är den mest komplexa. Vi måste importera ”Shortener”-modellen och formuläret. Vi använder fortfarande en funktion eftersom jag vill att du ska förstå dataflödet i vyn. Vi kommer också att använda en sökväg till en mall (som ännu inte har skapats).
Hemvy
''' Shortener views ''' from django.shortcuts import render # We will use it later from django.http import HttpResponse, Http404, HttpResponseRedirect # Model from .models import Shortener # Custom form from .forms import ShortenerForm # Create your views here. def home_view(request): template="urlshortener/home.html" context = {} # Empty form context['form'] = ShortenerForm() if request.method == 'GET': return render(request, template, context) elif request.method == 'POST': used_form = ShortenerForm(request.POST) if used_form.is_valid(): shortened_object = used_form.save() new_url = request.build_absolute_uri('/') + shortened_object.short_url long_url = shortened_object.long_url context['new_url'] = new_url context['long_url'] = long_url return render(request, template, context) context['errors'] = used_form.errors return render(request, template, context)
Vyn baseras på två villkor:
- När HTTP-metoden är GET: Vi skickar bara formuläret för Shortener som en kontext, som används för att skapa Shortener-objekt.
- När HTTP-metoden är POST: Vi skickar fortfarande formuläret i kontexten eftersom vi vill att användaren ska kunna ange en annan URL. Men vi skickar POST-förfrågan till ett annat formulär, ”used_form”.
Ett bra sätt att dynamiskt hämta webbplatsens fullständiga adress är att använda förfrågningsobjektets metod ”build_absolute_uri”.
>>> print(request.build_absolute_uri('/')) 'https://localhost:8080/'
För att hantera felaktiga förfrågningar (användaren anger en ogiltig URL), fångar vi in formulärfelen, skickar dem som kontext och återger mallen. Senare ska vi implementera felvisningen i mallen.
Omdirigeringsvy
Vyn ”redirect_url_view” är enklare. Det är en detaljerad vy, vilket innebär att den endast fungerar med ett objekt.
Denna funktion tar användarens förfrågan och den förkortade delen av URL:en som parametrar. Vi behöver inte kontrollera