【问题标题】:How to save related model instances before the model instance in django?如何在django中的模型实例之前保存相关的模型实例?
【发布时间】:2018-03-21 14:41:10
【问题描述】:

如何在实例模型之前保存相关模型实例。

这是必要的,因为我想在模型实例save方法下预处理相关模型的实例字段。

我正在处理 Django 项目,并且在所有相关的实例模型都保存在数据库中之后,我需要运行一些函数。

假设我有一个模型

models.py

from . import signals
class Video(models.Model):
    """Video model"""

    title = models.CharField(
        max_length=255,
        )

    keywords = models.ManyToManyField(
        KeyWord,
        verbose_name=_("Keywords")
    )

视频模型的新实例创建时。

我需要 1、先保存所有相关模型。 一种。如果相关模型为空,则返回空或无 2. 然后保存这个视频实例。

我尝试使用post_save 信号来做到这一点,但无法成功,因为无法保证相关模型会先于模型被保存。

from django.db.models.signals import post_save, pre_delete, m2m_changed
from django.dispatch import receiver

from .models import Video


@receiver(m2m_changed, sender=Video)
@receiver(post_save, sender=Video)
def index_or_update_video(sender, instance, **kwargs):
    """Update or create an instance to search server."""
    # TODO: use logging system
    # Grab the id
    print("Id is", instance.id)
    # Keywords is empty as keyword instance is saved later than this instace.
    keywords = [keyword.keyword for keyword in instance.keywords.all()]
    print(keywords) # [] empty no keywords
    instance.index()


@receiver(pre_delete, sender=Video)
def delete_video(sender, instance, **kwargs):
    print("Delete index object")
    instance.delete()

更新:

可以通过抓取post_save信号和等待单元来实现 当related_models 被保存时,它的相关模型被保存在数据库中 开始序列化过程并创建平面 json 文件以及模型字段及其相关实例,因此平面 json 文件可以索引 进入弹性搜索服务器。

还有一个问题,我们应该在信号处理方法中等待多少时间?以及如何知道所有与实例相关的字段都保存在数据库中。

class Video(models.Model):
    def save(self, *args, **kwargs): 
        # 1. Make sure all of its related items are saved in db 
        # 2. Now save this instance in db. 
        # 3. If the model has been saved. Serialize its value, 
        # 4. Serailize its related models fields 
        # 5. Save all the serialized data into index server 

        # The advantage of using this is the data are indexed in real 
        # time to index server. 

        # I tired to to implement this logic using signals, in case of 
        # signals, when the instance get saved, its related models are 
        # not instantly available in the databse. 

       # Other solution could be, grab the `post_save` signals, wait(delay
       # the serialization process) and start the serialization of 
       # instance model and it's related to convert the data to flat json 
       # file so, that it could index in the searching server(ES) in real 
       # time. 


       # until the instance related models get saved and start to 
       # serialize the data when its

【问题讨论】:

  • 您是否将关键字实例传递给关键字字段或字符串?
  • @scriptmonster 关键字实例

标签: python django django-models django-signals django-transmeta


【解决方案1】:

顺便说一下,我使用的是 django-admin,我没有定义其中的逻辑 一个视图,添加相关模型实例由 django admin 处理

在这种情况下,您可以颠倒 ModelAdmin 调用save_model()save_related() 的顺序,这样您就可以从Model.save() 获得相关字段的更新值,如this post 中所述。

class Video(models.Model):

    def save(self, *args, **kwargs): 
        if not self.id:
            super().save(*args, **kwargs)
        all_updated_keywards = self.keywards.all()
        ...
        super().save(*args, **kwargs)


class VideoAdmin(admin.ModelAdmin):

    def save_model(self, request, obj, form, change):
        if not obj.pk: 
            super().save_model(request, obj, form, change)
        else:
            pass 

    def save_related(self, request, form, formsets, change):
        form.save_m2m()
        for formset in formsets:
            self.save_formset(request, form, formset, change=change)
        super().save_model(request, form.instance, form, change)

【讨论】:

    【解决方案2】:

    您可以在保存实例之前覆盖模型的save() 方法并保存相关模型(对象)。

    【讨论】:

    • 我知道如何覆盖 save() 方法,但你能告诉我一个覆盖相关模型方法实例的例子
    • 你能给我更多的代码吗?你到底在做什么相关的对象?
    • 创建新实例(视频)时,您需要先保存它,然后再将关键字连接到此实例。之后(或者如果您使用现有实例),您可以使用 instance.keywords.add(keywords_query) 它将调用 m2m_changed(而不是 post_save)。你展示了模型,但是你如何使用这些实例以及如何保存它?
    • 顺便说一句,我使用的是 django-admin 并且我没有在视图中定义逻辑,添加相关模型实例由 django admin 处理
    • 如果你意识到你的管理类覆盖了 ModelAdmin,你可以覆盖方法 save_related 和 save_model。或者您是否尝试更改调用基本方法(save_model 和 save_related)的顺序?
    猜你喜欢
    • 2018-07-03
    • 2019-02-25
    • 2019-08-01
    • 2011-01-29
    • 2022-01-24
    • 1970-01-01
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多