# Django 6.0.5 documentation

# Avancerad handledning: Hur man skriver återanvändbara appar

Denna avancerade handledning börjar där Handledning 8 slutade. Vi kommer att förvandla vår webbenkät till ett fristående Python-paket som du kan återanvända i nya projekt och dela med andra människor.

Om du inte nyligen har slutfört Tutorials 1-8, uppmanar vi dig att gå igenom dessa så att ditt exempelprojekt överensstämmer med det som beskrivs nedan.

## Återanvändbarhet är viktigt

Det är mycket arbete att designa, bygga, testa och underhålla en webbapplikation. Många Python- och Django-projekt delar gemensamma problem. Skulle det inte vara bra om vi kunde spara en del av detta upprepade arbete?

Återanvändbarhet är livsstilen i Python. Python Package Index (PyPI) har ett stort utbud av paket som du kan använda i dina egna Python-program. Kolla in Django Packages för befintliga återanvändbara appar som du kan införliva i ditt projekt. Django i sig är också ett normalt Python-paket. Det innebär att du kan ta befintliga Python-paket eller Django-appar och komponera dem till ditt eget webbprojekt. Du behöver bara skriva de delar som gör ditt projekt unikt.

Låt oss säga att du startar ett nytt projekt som behöver en app för opinionsundersökningar, som den vi har arbetat med. Hur gör du den här appen återanvändbar? Lyckligtvis, du är på god väg redan. I Tutorial 1 såg vi hur vi kunde frikoppla polls från URLconf på projektnivå med hjälp av en `include`. I den här handledningen tar vi ytterligare steg för att göra appen enkel att använda i nya projekt och redo att publicera så att andra kan installera och använda den.

Paket? App?

En Python package ger ett sätt att gruppera relaterad Python-kod för enkel återanvändning. Ett paket innehåller en eller flera filer med Python-kod (även kända som ”moduler”).

Ett paket kan importeras med `import foo.bar` eller `from foo import bar`. För att en katalog (som `polls`) ska utgöra ett paket måste den innehålla en speciell fil `__init__.py`, även om denna fil är tom.

En Django applikation är ett Python-paket som är specifikt avsett för användning i ett Django-projekt. En applikation kan använda vanliga Django-konventioner, till exempel att ha undermoduler för `modeller`, `tester`, `urls` och `vyer`.

Senare använder vi termen packaging för att beskriva processen att göra ett Python-paket enkelt för andra att installera. Vi vet att det kan vara lite förvirrande.

## Ditt projekt och din återanvändbara app

Efter de tidigare handledningarna bör vårt projekt se ut så här:

    djangotutorial/
        manage.py
        mysite/
            __init__.py
            settings.py
            urls.py
            asgi.py
            wsgi.py
        polls/
            __init__.py
            admin.py
            apps.py
            migrations/
                __init__.py
                0001_initial.py
            models.py
            static/
                polls/
                    images/
                        background.png
                    style.css
            templates/
                polls/
                    detail.html
                    index.html
                    results.html
            tests.py
            urls.py
            views.py
        templates/
            admin/
                base_site.html

Du skapade `djangotutorial/templates` i Tutorial 7, och `polls/templates` i Tutorial 3. Nu kanske det är tydligare varför vi valde att ha separata mallkataloger för projektet och applikationen: allt som är en del av pollsapplikationen finns i `polls`. Det gör applikationen fristående och lättare att släppa in i ett nytt projekt.

Katalogen `polls` kan nu kopieras till ett nytt Django-projekt och omedelbart återanvändas. Den är dock inte riktigt redo att publiceras. För det måste vi paketera appen för att göra det enkelt för andra att installera den.

## Installera vissa förutsättningar

Det nuvarande läget för Python-paketering är lite förvirrat med olika verktyg. För denna handledning kommer vi att använda setuptools för att bygga vårt paket. Det är det rekommenderade förpackningsverktyget (sammanslaget med `distribute`-gaffeln). Vi kommer också att använda pip för att installera och avinstallera det. Du bör installera dessa två paket nu. Om du behöver hjälp kan du läsa så här installerar du Django med pip. Du kan installera `setuptools` på samma sätt.

## Paketera din app

Python packaging hänvisar till att förbereda din app i ett specifikt format som enkelt kan installeras och användas. Django själv är förpackat mycket på detta sätt. För en liten app som polls är denna process inte alltför svår.

1. Först skapar du en överordnad katalog för paketet, utanför ditt Django-projekt. Kalla den här katalogen `django-polls`.

   Välja ett namn för din app

   När du väljer ett namn för ditt paket, kontrollera PyPI för att undvika namnkonflikter med befintliga paket. Vi rekommenderar att du använder ett `django-`-prefix för paketnamn, för att identifiera ditt paket som specifikt för Django, och ett motsvarande `django_`-prefix för ditt modulnamn. Till exempel innehåller paketet `django-ratelimit` modulen `django_ratelimit`.

   Applikationsetiketter (det vill säga den sista delen av den prickade sökvägen till applikationspaket) måste vara unika i `INSTALLED_APPS`. Undvik att använda samma etikett som någon av Django contrib-paketen, till exempel `auth`, `admin` eller `messages`.

2. Flytta katalogen `polls` till katalogen `django-polls` och döp om den till `django_polls`.

3. Edit `django_polls/apps.py` so that `name` refers to the new module name, add `label` to give a short name for the app, and set `default_auto_field` to ensure your migrations are not affected by changes to `DEFAULT_AUTO_FIELD` made by users of your reusable app:

   `django-polls/django_polls/apps.py`

       from django.apps import AppConfig

       class PollsConfig(AppConfig):
           default_auto_field = "django.db.models.BigAutoField"
           name = "django_polls"
           label = "polls"

4. Skapa en fil `django-polls/README.rst` med följande innehåll:

   `django-polls/README.rst`

       ============
       django-polls
       ============

       django-polls is a Django app to conduct web-based polls. For each
       question, visitors can choose between a fixed number of answers.

       Detailed documentation is in the "docs" directory.

       Quick start
       -----------

       1. Add "polls" to your INSTALLED_APPS setting like this::

           INSTALLED_APPS = [
               ...,
               "django_polls",
           ]

       2. Include the polls URLconf in your project urls.py like this::

           path("polls/", include("django_polls.urls")),

       3. Run ``python manage.py migrate`` to create the models.

       4. Start the development server and visit the admin to create a poll.

       5. Visit the ``/polls/`` URL to participate in the poll.

5. Skapa en fil med namnet `django-polls/LICENSE`. Att välja en licens ligger utanför ramen för denna handledning, men det räcker med att säga att kod som släpps offentligt utan licens är användbar. Django och många Django-kompatibla appar distribueras under BSD-licensen; du är dock fri att välja din egen licens. Var bara medveten om att ditt licensval kommer att påverka vem som kan använda din kod.

6. Därefter skapar vi filen `pyproject.toml` som beskriver hur appen ska byggas och installeras. En fullständig förklaring av den här filen ligger utanför ramen för denna handledning, men Python Packaging User Guide har en bra förklaring. Skapa filen `django-polls/pyproject.toml` med följande innehåll:

   `django-polls/pyproject.toml`

       [build-system]
       requires = ["setuptools>=77.0.3"]
       build-backend = "setuptools.build_meta"

       [project]
       name = "django-polls"
       version = "0.1"
       dependencies = [
           "django>=X.Y",  # Replace "X.Y" as appropriate
       ]
       description = "A Django app to conduct web-based polls."
       readme = "README.rst"
       license = "BSD-3-Clause"
       requires-python = ">= 3.12"
       authors = [
           {name = "Your Name", email = "yourname@example.com"},
       ]
       classifiers = [
           "Environment :: Web Environment",
           "Framework :: Django",
           "Framework :: Django :: X.Y",  # Replace "X.Y" as appropriate
           "Intended Audience :: Developers",
           "Operating System :: OS Independent",
           "Programming Language :: Python",
           "Programming Language :: Python :: 3",
           "Programming Language :: Python :: 3 :: Only",
           "Programming Language :: Python :: 3.12",
           "Programming Language :: Python :: 3.13",
           "Programming Language :: Python :: 3.14",
           "Topic :: Internet :: WWW/HTTP",
           "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
       ]

       [project.urls]
       Homepage = "https://www.example.com/"

7. Många vanliga filer och Python-moduler och -paket ingår i paketet som standard. För att inkludera ytterligare filer måste vi skapa en fil `MANIFEST.in`. För att inkludera mallarna och de statiska filerna skapar du en fil `django-polls/MANIFEST.in` med följande innehåll:

   `django-polls/MANIFEST.in`

       recursive-include django_polls/static *
       recursive-include django_polls/templates *

8. Det är valfritt, men rekommenderas, att inkludera detaljerad dokumentation med din app. Skapa en tom katalog `django-polls/docs` för framtida dokumentation.

   Observera att katalogen `docs` inte kommer att ingå i ditt paket om du inte lägger till några filer i den. Många Django-appar tillhandahåller också sin dokumentation online via webbplatser som readthedocs.org.

   Många Python-projekt, inklusive Django och Python självt, använder Sphinx för att bygga sin dokumentation. Om du väljer att använda Sphinx kan du länka tillbaka till Djangos dokumentation genom att konfigurera Intersphinx och inkludera ett värde för Django i ditt projekts `intersphinx_mapping` värde:

       intersphinx_mapping = {
           # ...
           "django": (
               "https://docs.djangoproject.com/en/stable/",
               None,
           ),
       }

   Med det på plats kan du sedan korslänka till specifika poster, på samma sätt som i Django-dokumenten, till exempel ”`:attr:`django.test.TransactionTestCase.databases`”.

9. Kontrollera att paketet build är installerat (`python -m pip install build`) och försök bygga ditt paket genom att köra `python -m build` inuti `django-polls`. Detta skapar en katalog som heter `dist` och bygger ditt nya paket till källkods- och binärformat, `django_polls-0.1.tar.gz` och `django_polls-0.1-py3-none-any.whl`.

Mer information om paketering finns i Pythons Tutorial on Packaging and Distributing Projects.

## Använda ditt eget paket

Eftersom vi flyttade katalogen `polls` ut ur projektet fungerar den inte längre. Vi ska nu åtgärda detta genom att installera vårt nya paket `django-polls`.

Installera som ett användarbibliotek

Följande steg installerar `django-polls` som ett användarbibliotek. Installationer per användare har många fördelar jämfört med att installera paketet i hela systemet, till exempel att det kan användas på system där du inte har administratörsbehörighet samt att förhindra att paketet påverkar systemtjänster och andra användare av maskinen.

Observera att installationer per användare fortfarande kan påverka beteendet hos systemverktyg som körs som den användaren, så att använda en virtuell miljö är en mer robust lösning (se nedan).

1. För att installera paketet använder du pip (du har redan installerat det, eller hur?):

       python -m pip install --user django-polls/dist/django_polls-0.1.tar.gz

2. Uppdatera `mysite/settings.py` för att peka på det nya modulnamnet:

       INSTALLED_APPS = [
           "django_polls.apps.PollsConfig",
           ...,
       ]

3. Uppdatera `mysite/urls.py` för att peka på det nya modulnamnet:

       urlpatterns = [
           path("polls/", include("django_polls.urls")),
           ...,
       ]

4. Kör utvecklingsservern för att bekräfta att projektet fortsätter att fungera.

## Publicera din app

Nu när vi har paketerat och testat `django-polls`, är det redo att dela med sig till världen! Om detta inte bara var ett exempel, kan du nu:

- Skicka paketet till en vän via e-post.

- Ladda upp paketet på din webbplats.

- Post the package on a public repository, such as the Python Package Index (PyPI). There is a good tutorial for doing this.

## Installera Python-paket med en virtuell miljö

Tidigare installerade vi `django-polls` som ett användarbibliotek. Detta har några nackdelar:

- Om du ändrar användarbiblioteken kan det påverka andra Python-program på ditt system.

- Du kommer inte att kunna köra flera versioner av det här paketet (eller andra med samma namn).

Vanligtvis uppstår dessa situationer först när du underhåller flera Django-projekt. När de gör det är den bästa lösningen att använda venv. Med det här verktyget kan du underhålla flera isolerade Python-miljöer, var och en med sin egen kopia av biblioteken och paketnamnrymden.