Singleton w Django
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!!**