Es gibt viele Fälle, in denen Sie einen verknüpften Datensatz erstellen möchten, wenn Sie einen Datensatz auf der Site registrieren oder einen Datensatz mithilfe der API hinzufügen. Dieses Mal habe ich versucht, den Code, der ihn realisiert, mit verschiedenen Mustern von Django zusammenzufassen. Bitte beachten Sie, dass die hier angegebenen Beispiele nur diejenigen sind, die Sie implementiert haben, sodass Sie sie auf viele andere Arten implementieren können.
Es gibt auch eine Implementierung im Django-Rest-Framework (DRF).
Django
Das einfachste und vielseitigste Muster ist die Verwendung von Signalen. Wenn in Django eine bestimmte Aktion ausgeführt wird, wird ein entsprechendes Signal gesendet, und ein bestimmter Prozess kann ausgeführt werden.
from django.contrib.auth.models import AbstractBaseUser
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.crypto import get_random_string
class User(AbstractBaseUser):
pass
class Token(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='token')
token = models.CharField("Zeichen", max_length=40)
@receiver(post_save, sender=User)
def create_token(sender, **kwargs):
"""Token beim Erstellen eines Benutzers generieren"""
if kwargs['created']:
#Holen Sie sich anstelle von Hash, weil es ein Beispiel ist_random_string
Token.objects.create(user=kwargs['instance'],
token=get_random_string(length=40))
Da es sich beim Speichern des Datensatzes um ein Signal handelt, empfängt es das Signal "post_save". Verwenden Sie für die Funktion, die das Signal empfängt, den Dekorator "@ Empfänger".
Beim Erstellen ist kwargs ['created'] = True
.
Die erstellte Instanz wird in kwargs ['instance']
gespeichert, mit dem verwandte Datensätze erstellt werden können.
Der Vorteil der Verwendung von Signalen besteht darin, dass Sie auch verwandte Datensätze generieren können, indem Sie Datensätze von der Verwaltungssite hinzufügen. Da es von jeder Erstellungsmethode wie Verwaltungssite, Shell, Formular oder API ausgeführt wird, kann es in verschiedenen Mustern verwendet werden. Umgekehrt bedeutet dies auch, dass in jeder Situation Datensätze erstellt werden.
Djangos Design empfiehlt, mit Model Manager zusammenzuarbeiten, um mit Datensätzen zu arbeiten. Erstellen Sie eine Methode zum Erstellen von Datensätzen in ModelManager und erstellen Sie verwandte Objekte innerhalb dieser Methode.
from django.contrib.auth.models import BaseUserManager
class UserManager(BaseUserManager):
use_in_migrations = True
def create_user_and_token(self, email, password, **extra_fields):
if not email:
raise ValueError('The given username must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
#Verwandte Objekte erstellen
Token.objects.create(user=user,
token=get_random_string(length=40))
return user
class User(AbstractBaseUser):
objects = UserManager()
Wenn Sie ihm einen beschreibenden Namen wie "create_user_and_token" geben, Das Gute ist, dass Sie erkennen können, dass es sich um eine Methode handelt, mit der auch verwandte Objekte erstellt werden.
Sie können auch Argumente übergeben, selbst wenn sich die Struktur des zugeordneten Objekts ändert Es ist einfach zu warten, da Sie nur diese Methode ändern müssen.
Mit generic.CreateView
kann dies erreicht werden, indem ein wenig form_valid geschrieben wird.
from django.views.generic import CreateView
from django.contrib import messages
class View(CreateView):
form_class = UserModelFormClass # modelForm
def form_valid(self, form):
self.object = form.save()
#Verwandte Objekte erstellen
token = Token.objects.create(user=self.object,
token=get_random_string(length=40))
messages.success(self.request, f"Ich habe auch ein Token erstellt: {token.token}")
return HttpResponseRedirect(self.get_success_url())
Der Vorteil ist, dass eine relativ geringe Beschreibung erforderlich ist. CreateView wird häufig zum Erstellen von Datensätzen verwendet, daher ist es eine der Optionen. Wenn Sie eine Nachricht mit dem erstellten Objekt anzeigen möchten, sollten Sie sie hier beschreiben.
Django REST Framework
In DRF können Sie im Serializer ein Feld mit dem Namen "SerializerMethodField" definieren.
Der in diesem Feld definierte Wert gibt den Rückgabewert der Methode get_ <Feldname>
zurück.
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
token = serializers.SerializerMethodField()
class Meta:
model = User
fields = (
'pk',
'email',
'name',
'password',
'profile',
'token',
)
def get_token(self, instance):
#Instanz enthält die erstellte Instanz
return APIToken.object.create(instance).token
Es ist ein guter Punkt, einfach schreiben zu können, wenn verwandte Werte zurückgegeben werden, die gleichzeitig beim Erstellen von Daten mit der API erstellt wurden. Durch Überschreiben des "Erstellens" des "ViewSet" wird die Ansicht tendenziell länger.
Um ehrlich zu sein, denke ich, dass es für die meisten Anwendungsfälle besser ist, Signale zu verwenden oder Erstellungsmethoden zu implementieren, aber mir wurde vorgestellt, dass es einige Stellen gibt, an denen ich klar schreiben kann.
Recommended Posts