Evgenii Legotckoi
Evgenii Legotckoi8. Februar 2022 06:55

Django - Tutorial 055. Wie man die Funktion zum automatischen Auffüllen von Feldern schreibt

Ich wollte schon lange einen Artikel darüber schreiben, wie man auto populate field -Funktionalität für ein Django -Projekt schreibt. Dies ist eine sehr nützliche Funktion, mit der Sie den Inhalt anderer Modellfelder in Django ändern können, indem Sie einen Wert für ein Feld festlegen, das automatisch ausgefüllt wird.

Erstens, warum wird es benötigt? - Mit dieser Funktion können Sie die Größe des Codes an den Stellen reduzieren, an denen Sie andere Felder des Objekts neu schreiben müssen, wenn sie sich ändern. Das heißt, Sie müssen beispielsweise die Speichermethode nicht jedes Mal neu definieren, um ein Feld neu zu schreiben, falls sich andere Felder des Objekts ändern. Außerdem ist die Verwendung der automatischen Auffüllung im Grunde eine fortgeschrittenere und übersichtlichere Möglichkeit, Datenmodelle in Django zu verwalten.
Und auch ein ähnlicher Ansatz kann einige Probleme lösen und die Website verbessern.


Beschreibung der Vorgehensweise am Beispiel von Markdown-Feldern

Diesen Ansatz verwende ich beispielsweise auf dieser Seite zum Verfassen von Inhalten von Kommentaren und Artikeln und allgemein in allen Bereichen, in denen die Markdown -Syntax verwendet wird.

Wie es funktioniert?

  • Alle Datenmodelle haben zwei Felder content und content_markdown . Das Feld content_markdown steuert den Inhalt des Felds content . Das heißt, in einer normalen Situation hat der Benutzer keinen Zugriff, um die Inhalte des Felds Inhalt zu bearbeiten, er bearbeitet immer nur das Feld Inhalt_Markdown .
  • Der Benutzer bearbeitet beim Erstellen einer Nachricht das Feld content_markdown , das automatisch html -Code aus dem Markup markdown generiert und html in das Feld content schreibt .

Warum wird das benötigt?

Jeder entscheidet selbst, warum er Auto-Fill verwenden sollte. Beispielsweise können Sie automatisch ein Miniaturbild aus einem Quellbild generieren. Eine solche Funktionalität ist ideal für solche Aktionen.

Und speziell in meinem Fall stellte sich heraus, dass ich keine passende Funktionalität zum Generieren von HTML aus Markdown gefunden habe. Alles, was ich damals gefunden habe, waren Bibliotheken, die zur Laufzeit bei jedem Seitenaufruf mithilfe von Template-Tags HTML generierten. Und dieser Ansatz reduziert die Leistung der Website erheblich. Daher habe ich für mich entschieden, dass ich bereit bin, Speicherplatz für die Leistung der Website zu opfern. Denn eine Verzehnfachung der Seitenladegeschwindigkeit ist in manchen Fällen einer Verdopplung des belegten Speicherplatzes eindeutig vorzuziehen.

Implementierung

Ich werde einen vereinfachten MarkdownField -Code präsentieren, den Sie auf Ihrer Website verwenden könnten.

MarkdownField

MarkdownField erbt vom standardmäßigen TextField und nimmt als Argument den Namen des Felds, das für html -Inhalte verwendet werden soll. Dies ist das html_field -Argument.

Dieses Feld hat eine set_html -Methode, die dafür verantwortlich ist, html aus dem markdown -Markup zu generieren und auch den Wert im html -Feld des Inhalts festzulegen.

Der wichtige Punkt ist, die Methode set_html mit dem Signal pre_save in der Methode contribute_to_class zu verbinden. Eine frühere Version, die ich entwickelt habe, hatte den Nachteil, dass jedes Mal, wenn ein Objekt angefordert wurde, die html-generierende Methode aufgerufen wurde. Es war ein Fehler, den ich später entdeckt und auf ähnliche Weise korrigiert habe. Jetzt wird der Inhalt nur generiert, wenn das Objekt gespeichert wird.

# -*- coding: utf-8 -*-

from django.db import models
from django.db.models.signals import pre_save

from .utils import MarkdownWorker


class MarkdownField(models.TextField):
    """
    This field save markdown text with auto-populate text to html field.
    This field must be used with second text field for html content.
    """

    def set_html(self, instance=None, update_fields=None, **kwargs):
        value = getattr(instance, self.attname)
        if value and len(value) > 0:
            instance.__dict__[self.html_field] = MarkdownWorker(value).get_text()

    def contribute_to_class(self, cls, name, **kwargs):
        super().contribute_to_class(cls, name, **kwargs)
        pre_save.connect(self.set_html, sender=cls)

    def __init__(self, html_field=None, *args, **kwargs):
        self.html_field = html_field
        super().__init__(*args, **kwargs)

MarkdownWorker

Diese Klasse ist für das Generieren von HTML-Inhalten aus Markdown-Markup verantwortlich. In dieser Klasse können Sie beliebige zusätzliche Verarbeitungsarten aus HTML hinzufügen, um das gewünschte Endergebnis zu erhalten. Beispielsweise können Sie Links oder Bilder entfernen, von denen Sie glauben, dass der Benutzer sie nicht hinzufügen kann.

Beim Erstellen eines Objekts der Klasse MarkdownWorker wird der zu verarbeitende Text festgelegt und anschließend eine Methode aufgerufen, die den Text in html umwandelt.

Auch in meinem Fall werden Erweiterungen verwendet für:

  • Tabellengenerierung
  • Code-Unterstützung
  • Transferzusätze
  • Obere und untere Syntax
# -*- coding: utf-8 -*-

import markdown

class MarkdownWorker:
    """
    Markdown converter. It will convert markdown text to html text
    """
    def __init__(self, text):
        self.pre_markdown_text = text
        self.markdown_text = None
        self.make_html_from_markdown()

    def make_html_from_markdown(self):
        if self.pre_markdown_text:
            self.markdown_text = markdown.markdown(
                self.pre_markdown_text,
                extensions=['markdown.extensions.attr_list',
                            'markdown.extensions.tables',
                            'markdown.extensions.fenced_code',
                            'markdown.extensions.nl2br',
                            'superscript',
                            'subscript'],
                output_format='html5'
            )

    def get_text(self):
        return self.markdown_text

Um all diese Funktionen zu unterstützen, müssen Sie die Bibliotheken installieren:

  • Markdown
  • MarkdownSubscript
  • MarkdownHochgestellt

Vielleicht auch beautifulsoup4 , oder es wird in Abhängigkeiten installiert, aber ehrlich gesagt, ich erinnere mich nicht.

Anwendung

Und jetzt wenden wir dieses Feld im Datenmodell an.

Wir haben ein Post-Modell, das die Felder enthält:

  • Benutzer - Fremdschlüssel pro Benutzer
  • Inhalt - Feld, das HTML-Inhalt enthält
  • content_markdown - das Feld, in dem der Markdown-Text mit anschließender Generierung von HTML-Text gespeichert wird. Dabei sieht man, dass ihm das Argument html_field='content' übergeben wird, das angibt, mit welchem Feld das MarkdownField arbeiten soll.
# -*- coding: utf-8 -*-

from django.conf import settings
from django.db import models
from django.utils.translation import gettext_lazy as _

from .fields import MarkdownField


class Post(models.Model):
    user = models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

    content = models.TextField(verbose_name=_('Description'))
    content_markdown = MarkdownField(verbose_name=_('Description - Markdown'), html_field='content')

Fazit

Auf diese Weise können Sie Ihrer Website Markdown-Felder hinzufügen, die automatisch HTML-Inhalte generieren.
Sie haben jetzt Unterstützung für ausgefallene Markdown-Syntax auf Ihrer Website, die automatisch HTML-Inhalte generiert.

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

Kommentare

Nur autorisierte Benutzer können Kommentare posten.
Bitte Anmelden oder Registrieren
Letzte Kommentare
ИМ
Игорь Максимов5. Oktober 2024 07:51
Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55. Juli 2024 11:02
QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssr8. Februar 2024 18:43
Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25. Dezember 2023 10:30
Boost - statisches Verknüpfen im CMake-Projekt unter Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
Jetzt im Forum diskutieren
J
JacobFib17. Oktober 2024 03:27
добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
JW
Jhon Wick1. Oktober 2024 15:52
Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
КГ
Кирилл Гусарев27. September 2024 09:09
Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
F
Fynjy22. Juli 2024 04:15
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

Folgen Sie uns in sozialen Netzwerken