Как создать страницу статических настроек для сайта в админке Django?

Необходимо реализовать простую страницу с настройками, где будут перечислены(к примеру):
* название сайта
* адрес
*телефон
* другая статическая информация
Я понимаю что можно создать простую модель и оттуда брать параметры, но как-то это некрасиво получается(смущает возможность добавить еще страницу)

Должно быть более элегантное решение.
  • Вопрос задан
  • 1636 просмотров
Решения вопроса 1
@deliro
from datetime import timedelta

from django.db import models
from django.utils import timezone


class Settings(models.Model):
    """
    Модель настроек с интерфейсом атрибутов

    >>> settings.hello = 'world'
    Сохранит модель с key='hello' и value='world'. Если модель с таким ключом до этого
    существовала (т.е. в данный момент мы меняем значение), запись в БД поменяется и кэш
    инвалидируется.

    >>> settings.hello
    'world'
    Получение ключа. Сначала ищет в кэше. Если находит - возвращает, если нет,
    ищет в БД запись с таким ключом (hello). Если находит - кладёт в кэш и возвращает.

    >>> del settings.hello
    Удаляет запись с ключом hello из БД и кэша.
    
    Также, ключ и значение можно редактировать из админки (кэш в этом случает также
    инвалидируется)

    Пример куска вьюхи, которая может редактировать настройки сайта:
    if form.is_valid():
        settings.phone = form.cleaned_data['phone']
        settings.address = form.cleaned_data['address']
    """
    key = models.CharField(max_length=255, primary_key=True)
    value = models.TextField()

    __cache_ttl = 60 * 60
    __cache = {}
    __cache_max_size = 300

    def save(self, *args, **kwargs):
        super(Settings, self).save(*args, **kwargs)
        self._cache_invalidate(self.key)

    def __setattr__(self, key, value):
        cls = type(self)
        try:
            instance = cls.objects.get(key=key)
            instance.value = value
            instance.save()
        except cls.DoesNotExist:
            cls.objects.create(key=key, value=value)
        self._cache_invalidate(key)


    def __getattr__(self, key):
        value = self._cache_get(key)
        if value is None:
            cls = type(self)
            try:
                value = cls.objects.get(key=key).value
                self._cache_set(key, value)
            except cls.DoesNotExist:
                value = None 
        return value

    def __delattr__(self, key):
        type(self).objects.filter(key=key).delete()
        self._cache_invalidate(key)

    def _cache_set(self, key, value):
        if len(self.__cache) < self.__cache_max_size:
            self._cache_force_set(key, value)
        else:
            self._cache_remove_old()
            if len(self.__cache) < self.__cache_max_size:
                self._cache_force_set(key, value)

    def _cache_force_set(self, key, value):
        self.__cache[key] = (
            value,
            timezone.now() + timedelta(seconds=self.__cache_ttl)
        )

    def _cache_get(self, key):
        result = self.__cache.get(key)
        if result[1] > timezone.now():
            self._cache_invalidate(key)
            return None
        return result[0]

    def _cache_invalidate(self, key):
        del self.__cache[key]

    def _cache_remove_old(self):
        now = timezone.now()
        for k, v in self.__cache.items():
            if v[1] < now:
                self._cache_invalidate(k)

settings = Settings()


И в контекст процессоры добавить:

def settings(request):
    return {'settings': settings}


Ну и в любом шаблоне:
<title>{{ settings.title }}</title>
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы