我们希望在ManyToManyField
方法中预先保存相关的Model.save
数据,但是数据尚未通过Django ORM提供,因为它与ManyToManyField
相关post-save
1}}数据并且在主记录的ManyToMany
之前不会被设置。
以下是关系的一些示例代码以及Model.save
class Friend(models.Model):
name = models.CharField(max_length=50)
class Person(models.Model):
name = models.CharField(max_length=50)
friends = models.ManyToManyField(Friend)
def save(self, *args, **kwargs):
friends = self.friends.all()
# 'friends' is an empty QuerySet at this point
# I'd like to do something with friends here,
# but it gets set after save
super(Friend, self).save(*args, **kwargs)
记录的位置
friends
在save
上传递friend = Friend.objects.all()[0]
friend2 = Friend.objects.all()[1]
friends = [friend, friend2]
Person.objects.create(friends=friends)
的示例用例:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: white;" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
<children>
<StackPane layoutX="150.0" layoutY="115.0" prefHeight="200.0" prefWidth="300.0" style="-fx-border-color: black; -fx-background-color: white;">
<children>
<VBox prefHeight="200.0" prefWidth="100.0" spacing="10.0">
<children>
<HBox spacing="10.0">
<children>
<Label maxHeight="1.7976931348623157E308" text="Source" />
<TextField prefWidth="125.0" />
<Button mnemonicParsing="false" text="Browse.." />
</children>
</HBox>
<HBox spacing="10.0">
<children>
<Label maxHeight="1.7976931348623157E308" text="Report" />
<TextField maxWidth="125.0" />
<Button mnemonicParsing="false" text="Browse.." />
</children>
</HBox>
</children>
<StackPane.margin>
<Insets left="5.0" right="5.0" top="20.0" />
</StackPane.margin>
</VBox>
</children></StackPane>
<Label layoutX="164.0" layoutY="105.0" style="-fx-background-color: white;" text="Text IO Zone" />
</children>
</AnchorPane>
答案 0 :(得分:1)
m2m关系在实例保存后建立并获取它自己的ID,因此您无法在覆盖保存方法中访问它,这是两种方式:
一:在django 1.9之后,事务工具提供了监听数据库通信的新方法,doc是here。演示代码是:
from django.db import transaction
class Person(models.Model):
name = models.CharField(max_length=50)
friends = models.ManyToManyField(Friend)
def save(self, *args, **kwargs):
instance = super(Person, self).save(*args, **kwargs)
transaction.on_commit(self.update_friend)
return instance
def update_friend(self):
for friend in self.friends.all():
print(friend.__str__())
第二种方式是使用信号,这里是demo:
from django.db.models.signals import m2m_changed
@receiver(m2m_changed, sender=Person.friends.through)
def friends_change(sender, action, pk_set, instance=None, **kwargs):
if action in ['post_add', 'post_remove']:
queryset = instance.friends.all()
for friend in queryset:
print(friend.__str__())