Angenommen, Sie erstellen eine Website mit einem Django-basierten CMS, das über eine Art dynamischer Website-Einstellungen verfügen muss, die dem Benutzer zur Verfügung stehen. Zum Beispiel der Name der Website, einige Fachinformationen, während Sie die Möglichkeit der Mehrsprachigkeit berücksichtigen. Was kann man dann dafür verwenden? Ich hatte eine Idee, eine Datenbank zu verwenden.
Zur Umsetzung wird Folgendes benötigt:
- Erstellen eines Datenmodells, das immer nur ein Objekt enthält, dh nur einen Datensatz. Das heißt, es wird ein Singleton-Modell sein.
- Verhindern Sie das Löschen dieses Eintrags und das Erstellen neuer Einträge im Django-Admin
- Die Möglichkeit, Informationen aus diesem Modell direkt in der Vorlage zu verwenden, ohne Site-Einstellungen in die Ansichtsfunktion zu laden.
Sehen wir uns an, wie Sie dies implementieren.
SingletonModel
Ich habe auf GitHub den Code für ein abstraktes SingletonModel gefunden, das 2012 geschrieben wurde. Hier ist Link zum Inhalt .
Hier ist der Code für dieses SingletonModel
class SingletonModel(models.Model): class Meta: abstract = True def save(self, *args, **kwargs): self.__class__.objects.exclude(id=self.id).delete() super(SingletonModel, self).save(*args, **kwargs) @classmethod def load(cls): try: return cls.objects.get() except cls.DoesNotExist: return cls()
Das Modell in der save -Methode speichert beim Speichern des Objekts automatisch alle anderen, wodurch Sie immer nur eine Instanz dieses Modells in der Datenbank speichern können.
Die load -Methode nimmt ein einzelnes Einstellungsobjekt aus der Datenbank, wenn es kein Objekt in der Datenbank gibt, gibt sie eine neue Instanz dieses Modells zurück, die dann gespeichert werden muss.
Lassen Sie uns unsere eigene Einstellungsklasse erstellen, die wir in Zukunft für unsere Anforderungen verwenden können.
# -*- coding: utf-8 -*- from django.db import models from django.utils.translation import ugettext_lazy as _ from my_app.singleton_model import SingletonModel class SiteSettings(SingletonModel): site_url = models.URLField(verbose_name=_('Website url'), max_length=256) title = models.CharField(verbose_name=_('Title'), max_length=256) def __str__(self): return 'Configuration'
Einrichten des Admin-Panels
Jetzt müssen wir das Löschen dieses Eintrags und das Erstellen neuer Einträge im Django-Admin deaktivieren.
# -*- coding: utf-8 -*- from django.contrib import admin from django.db.utils import ProgrammingError from my_app.models import SiteSettings class SiteSettingsAdmin(admin.ModelAdmin): # Create a default object on the first page of SiteSettingsAdmin with a list of settings def __init__(self, model, admin_site): super().__init__(model, admin_site) # be sure to wrap the loading and saving SiteSettings in a try catch, # so that you can create database migrations try: SiteSettings.load().save() except ProgrammingError: pass # prohibit adding new settings def has_add_permission(self, request, obj=None): return False # as well as deleting existing def has_delete_permission(self, request, obj=None): return False admin.site.register(SiteSettings, SiteSettingsAdmin)
Die Einstellungen können jetzt im Python-Code verwendet werden.
Erstellen Sie einen Kontextprozessor, um Einstellungen in eine Vorlage zu laden
context_processors.py
# -*- coding: utf-8 -*- from evileg_settings.models import SiteSettings def load_settings(request): return {'site_settings': SiteSettings.load()}
settings.py
Dann verbinden wir load_settings
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', # Загружаем наши настройки при каждом рендеринге шаблона с контекстом 'my_app.context_processors.load_settings', ], }, }, ]
Verwendung in Vorlage
<h1>{{ site_settings.title }}</h1>
Fazit
So können Sie schnell und einfach einfache dynamische Seiteneinstellungen in Django implementieren und diese dann an alle für uns interessanten Seitenparameter binden.
Der Vorteil dieses Ansatzes wird die Möglichkeit sein, Fremdschlüssel für einige spezielle Daten auf der Website zu verwenden, sowie die Verwendung von Django-Modellübersetzungen, was bedeutet, dass es keine Probleme mit Mehrsprachigkeit geben wird.