访问相关的ManyToManyField数据预先保存在Django Model.save方法中

时间:2017-10-13 00:46:29

标签: python django

我们希望在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>

1 个答案:

答案 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__())