Als ich kürzlich mit Django erneut ein Modell für die Follow-Funktion erstellt habe, habe ich versucht, das Argument "through" zu verwenden, und ein Modell gefunden, das einfach zu schreiben ist. Deshalb habe ich es als Artikel geschrieben.
Ich habe es nicht besonders fortgeschritten geschrieben, aber als ich nach der Follow-Funktion gesucht habe, konnte ich ein solches Modell nicht finden. Ich hoffe, es ist hilfreich für diejenigen, die ähnliche Funktionen erstellen.
In Django gibt es drei Möglichkeiten, ein Modell zu schreiben, das viele zu viele darstellt.
#Anhänger von user1/Holen Sie sich alle Follower
user1.followers.all()
user1.followees.all()
#Artikelliste der Benutzer, denen Benutzer1 folgt(Timeline auf Twitter)Erhalten
Item.objects.filter(user__followers=user1)
#Benutzer1 folgt Benutzer2
user1.followee_friendships.create(followee=user2)
Sie können so schreiben.
class FriendShip(models.Model):
follower = models.ForeignKey('User', on_delete=models.CASCADE, related_name='followee_friendships')
followee = models.ForeignKey('User', on_delete=models.CASCADE, related_name='follower_friendships')
class Meta:
unique_together = ('follower', 'followee')
Ein Zwischenmodell, das Follow-Beziehungen darstellt. Folgen Sie dem "User" -Modell und zeigen Sie mit dem "Fremdschlüssel" auf jeden als Follower.
Das Argument "on_delete" lautet "models.CASCADE", da diese Beziehungen auch gelöscht werden sollten, wenn der Benutzer gelöscht wird. Wenn dadurch die Zieldaten von "Foreignkey" gelöscht werden, werden diese Daten ebenfalls automatisch gelöscht.
related_name Wenn Sie mehrere "Fremdschlüssel" für dieselbe Klasse verwenden, müssen Sie "related_name" festlegen. Andernfalls wird zum Zeitpunkt des Befehls "manage.py make migrations" eine Fehlermeldung angezeigt. Durch Einstellen dieser Option kann auf dieses Modell in der entgegengesetzten Richtung vom Verbindungsziel des externen Schlüssels verwiesen werden.
Hier verhält sich "follower_friendships" wie "Objekte". Beispielsweise haben die folgenden zwei Zeilen dieselbe Bedeutung.
Friendship.objects.create(follower=user1, followee=user2)
user1.followee_friendships.create(followee=user2)
Diese repräsentieren die Folgen von "Benutzer1" bis "Benutzer2".
unique_together Hiermit legen Sie eine Einschränkung fest, dass die Kombination eindeutig ist.
Es gibt immer eine Kombination von Followern für Follower, und das Erstellen mehrerer Follower ist ein abnormales Verhalten. Stellen Sie dies ein.
Darüber hinaus scheint es keinen Fehler zu geben, selbst wenn es ein Follow-and-Follow gibt, das umgekehrt ist (sogenanntes gegenseitiges Follow).
class User(AbstractUser):
followees = models.ManyToManyField(
'User', verbose_name='Benutzer folgen', through='FriendShip',
related_name='+', through_fields=('follower', 'followee')
)
followers = models.ManyToManyField(
'User', verbose_name='Benutzer werden verfolgt', through='FriendShip',
related_name='+', through_fields=('followee', 'follower')
)
AbstractUser
AbstractUser
dient zum Erweitern des Standardbenutzers. Es wird verwendet, wenn ein neues Feld überschrieben oder hinzugefügt wird, über das "Benutzer" bereits verfügt.
Hier finden Sie bereits einige bessere Informationen. Weitere Informationen finden Sie im Kommentar oder in der offiziellen Dokumentation.
ManyToManyField Das "FriendShip" -Modell wird im Argument "bis" angegeben. Jetzt können Sie die Daten über das Zwischenmodell abrufen, indem Sie "followees", "follers" aufrufen.
related_name Die Angabe von "+" zeigt an, dass keine Rückreferenz erforderlich ist. Die Dokumentation sagt:
If you’d prefer Django not to create a backwards relation, set related_name to '+' or end it with '+'. For example, this will ensure that the User model won’t have a backwards relation to this model:
https://docs.djangoproject.com/en/3.0/ref/models/fields/#django.db.models.ForeignKey.related_name
through_fields Wenn Sie auf eine und andere damit verbundene Daten in "ManyToManyField" als Quelle und Ziel abzielen, übergeben Sie "(Quelle, Ziel)" im Argument "through_fields".
user.followee
möchte die Verfolgung eines Benutzers erhalten, daher geben wir ('follower', 'followee')
an, und user.follower
gibt das Gegenteil an.
Wenn Sie eine Rückreferenz mit "related_name" angeben, benötigen Sie nur ein "ManyToManyField".
class User(AbstractUser):
followers = models.ManyToManyField(
'User', verbose_name='Benutzer werden verfolgt', through='FriendShip',
related_name='followees', through_fields=('followee', 'follower')
)
Es scheint jedoch unpraktisch zu sein, beispielsweise "verbose_name" nicht angeben zu können. Daher scheint es besser, zwei zu deklarieren.