Singleton w Django

in #polish7 years ago

Singleton to wzorzec projektowy, który umożliwia tworzenie tylko jednej i jedynej instancji danej klasy. Osobiście jak narazie nie widziałem potrzeby zastosowania go w moich projektach więc nie będę się rozpisywał na temat samej implementacji w danym języku. W tym artykule opiszę za to bardzo ciekawą aplikację w django która na tym modelu bazuje.

Django solo

Django Solo, bo o tej aplikacji myślałem pisząc poprzedni paragraf, umożliwia w bardzo prosty sposób tworzenie tabeli w bazie danych z jednym tylko rekordem. Oczywiście nasuwa się logiczne pytanie - po co mi to. Wymienię więc moje przypadki użycia:

  • przechowywanie metadanych strony

  • przechowywanie linków z footera

  • przechowywanie komunikatów

Mogłem oczywiście zahardkodować te dane w szablonie albo na przykład wrzucić je do ustawień (settings.py). Tak czy inaczej jako że pracuje na gicie to każda zmiana wiązałaby się z koniecznością zapuszczenia commita, ewentualnie musiałbym się logować na serwer produkcyjny i ręcznie za każdym razem edytować powiedzmy plik z ustawieniami. Nie jest to zbyt wygodne a tak implementując tę appkę u siebie mogę w łatwy sposób zmieniać dane z poziomu admina. Wygodna sprawa, ale pozostaje problem z zapytaniami do bazy danych. Takie 'singletony' generują oczywiście dodatkowe zapytania. Można się pogodzić z dodatkowym, stosunkowo małym narzutem albo zaprzyjaźnić się w końcu z cachowaniem.

Co i jak

Na początku zainstalowałem paczkę w swoim środowisku wirtualnym.

$ pip install django-solo

Później wprowadziłem nowy wpis do swojego pliku z zależnościami. Całość wyglądana następująco:

# Python
factory-boy==2.8.1

# Django/Apps
Django<1.12
django-markdownx==2.0.21
django-simple-captcha==0.5.5
django-cleanup==0.4.2
djangorestframework==3.6.3
####
django-solo==1.1.2
####
easy-thumbnails==2.4.1
django-cors-headers==2.1.0
django-fsm==2.6.0

# Django/Apps dependencies 
Pillow==3.3.1
Markdown==2.6.8

Dodałem też appkę do ustawień (może to nie jest konieczne, nie sprawdzałem tego).

### settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    ...
    'solo',
    ...
]

Przeszedłem do implementacji.

### Jakiś models.py

from solo.models import SingletonModel

class SiteMeta(SingletonModel):
    title = models.CharField(max_length=255, verbose_name='Tytuł')
    subheading = models.CharField(max_length=255, verbose_name='Podtytuł')
    description = models.CharField(max_length=255, verbose_name='Opis')
    keywords = models.CharField(max_length=255, verbose_name='Słowa kluczowe')
    author = models.CharField(max_length=255, verbose_name="Autor")
    image = models.ImageField(verbose_name="Obraz")

    def __str__(self):
        return "Ustawienia strony"

    class Meta:
        verbose_name = "Ustawienia strony"
### Jakiś admin.py

from django.contrib import admin
from .models import SiteMeta
from solo.admin import SingletonModelAdmin

admin.site.register(SiteMeta, SingletonModelAdmin)

Widok w panelu admina (standardowa lista zostaje zlikwidowana tak jak i przycisk 'dodaj'):

Jeśli chcemy dobrać się do Singletona wystarczy wywołać metodę:

site = SiteMeta.get_solo()

By zwrócić wartość pola:

site.nazwa_pola

End

I to by było na tyle! Mam nadzieję, że dzisiaj dowiedziałeś się czegoś nowego.

** See ya!!**