it-swarm.com.de

Django-Feld mit pre_save () füllen?

class TodoList(models.Model):
    title = models.CharField(maxlength=100)
    slug = models.SlugField(maxlength=100)
    def save(self):
        self.slug = title
        super(TodoList, self).save()

Ich gehe davon aus, dass das Erstellen von Slugs, wenn ein Titel in die Tabelle TodoList eingefügt wird, erstellt und gespeichert wird.

Wie auch immer, ich habe mir pre_save () als einen anderen Weg angesehen, aber ich kann nicht herausfinden, wie es funktioniert. Wie machst du das mit pre_save ()?

ist es so

def pre_save(self):
     self.slug = title

Ich vermute nein. Was ist der Code dafür?

Vielen Dank!

38
Derek

Höchstwahrscheinlich beziehen Sie sich auf Djangos pre_save Signal . Sie könnten so etwas einrichten:

from Django.db.models.signals import pre_save
from Django.dispatch import receiver
from Django.template.defaultfilters import slugify

@receiver(pre_save)
def my_callback(sender, instance, *args, **kwargs):
    instance.slug = slugify(instance.title)

Wenn Sie das Absenderargument wie @receiver(pre_save, sender=MyModel) nicht in das Dekorationsprogramm aufnehmen, wird der Rückruf für alle Modelle aufgerufen.

Sie können den Code in jede Datei einfügen, die während der Ausführung Ihrer App analysiert wird. models.py ist dafür ein guter Ort.

64
@receiver(pre_save, sender=TodoList)
def my_callback(sender, instance, *args, **kwargs):
    instance.slug = slugify(instance.title)
20
Leandro Souza

sie können Django-Signale verwenden.pre_save:

from Django.db.models.signals import post_save, post_delete, pre_save

class TodoList(models.Model):
    @staticmethod
    def pre_save(sender, instance, **kwargs):
        #do anything you want

pre_save.connect(TodoList.pre_save, TodoList, dispatch_uid="sightera.yourpackage.models.TodoList") 
11
Eyal Ch

Der Signalhaken pre_save() ist in der Tat ein großartiger Ort, um die Slugification für eine große Anzahl von Modellen zu handhaben. Der Trick besteht darin, zu wissen, für welche Modelle Slugs generiert werden müssen und auf welchem ​​Feld der Slug-Wert basieren soll.

Ich benutze dafür einen Klassendekorator, mit dem ich Modelle für die automatische Slug-Generierung markieren kann und auf welchem ​​Feld sie basieren sollen:

from Django.db import models
from Django.dispatch import receiver
from Django.utils.text import slugify

def autoslug(fieldname):
    def decorator(model):
        # some sanity checks first
        assert hasattr(model, fieldname), f"Model has no field {fieldname!r}"
        assert hasattr(model, "slug"), "Model is missing a slug field"

        @receiver(models.signals.pre_save, sender=model)
        def generate_slug(sender, instance, *args, raw=False, **kwargs):
            if not raw and not instance.slug:
                source = getattr(instance, fieldname)
                slug = slugify(source)
                if slug:  # not all strings result in a slug value
                    instance.slug = slug
        return model
    return decorator

Hiermit wird ein Signalhandler nur für bestimmte Modelle registriert, und Sie können das Quellfeld für jedes dekorierte Modell variieren:

@autoslug("name")
class NamedModel(models.Model):
    name = models.CharField(max_length=100)
    slug = models.SlugField()

@autoslug("title")
class TitledModel(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField()

Beachten Sie, dass nicht versucht wird, einen eindeutigen Slug-Wert zu generieren. Dies würde die Überprüfung auf Integritätsausnahmen in einer Transaktion oder die Verwendung eines zufälligen Werts in der Datenmenge aus einem Pool erfordern, der groß genug ist, um Kollisionen unwahrscheinlich zu machen. Die Prüfung von Integritätsausnahmen kann nur in der save() -Methode durchgeführt werden, nicht in Signal-Hooks.

1
Martijn Pieters

Empfängerfunktionen müssen so sein:

def my_callback(sender, **kwargs):
    print("Request finished!")

Beachten Sie, dass die Funktion ein sender -Argument zusammen mit den Platzhalter-Schlüsselwortargumenten (** kwargs); Alle Signalhandler müssen diese Argumente akzeptieren.

Alle Signale senden Schlüsselwortargumente und können diese Schlüsselwortargumente jederzeit ändern.

Referenz hier .

0
Rockallite