久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

在 Django 中復(fù)制模型實(shí)例及其相關(guān)對(duì)象/用于遞歸

Duplicating model instances and their related objects in Django / Algorithm for recusrively duplicating an object(在 Django 中復(fù)制模型實(shí)例及其相關(guān)對(duì)象/用于遞歸復(fù)制對(duì)象的算法) - IT屋-程序員軟件開(kāi)發(fā)技術(shù)分享社
本文介紹了在 Django 中復(fù)制模型實(shí)例及其相關(guān)對(duì)象/用于遞歸復(fù)制對(duì)象的算法的處理方法,對(duì)大家解決問(wèn)題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧!

問(wèn)題描述

我有 BooksChaptersPages 的模型.它們都是由 User 編寫(xiě)的:

I've models for Books, Chapters and Pages. They are all written by a User:

from django.db import models

class Book(models.Model)
    author = models.ForeignKey('auth.User')

class Chapter(models.Model)
    author = models.ForeignKey('auth.User')
    book = models.ForeignKey(Book)

class Page(models.Model)
    author = models.ForeignKey('auth.User')
    book = models.ForeignKey(Book)
    chapter = models.ForeignKey(Chapter)

我想做的是復(fù)制現(xiàn)有的 Book 并將它的 User 更新給其他人.皺紋是我還想將所有相關(guān)的模型實(shí)例復(fù)制到 Book - 所有的 ChaptersPages 也是如此!

What I'd like to do is duplicate an existing Book and update it's User to someone else. The wrinkle is I would also like to duplicate all related model instances to the Book - all it's Chapters and Pages as well!

當(dāng)查看 Page 時(shí),事情變得非常棘手 - 新的 Pages 不僅需要更新其 author 字段,而且它們會(huì)還需要指向新的Chapter對(duì)象!

Things get really tricky when look at a Page - not only will the new Pages need to have their author field updated but they will also need to point to the new Chapter objects!

Django 支持開(kāi)箱即用的方式嗎?復(fù)制模型的通用算法是什么樣的?

Does Django support an out of the box way of doing this? What would a generic algorithm for duplicating a model look like?

干杯,

約翰

更新:

上面給出的類只是說(shuō)明我遇到的問(wèn)題的一個(gè)例子!

The classes given above are just an example to illustrate the problem I'm having!

推薦答案

這不再適用于 Django 1.3,因?yàn)?CollectedObjects 已被刪除.請(qǐng)參閱 變更集 14507

This no longer works in Django 1.3 as CollectedObjects was removed. See changeset 14507

我在 Django Snippets 上發(fā)布了我的解決方案. 它主要基于 django.db.models.query.CollectedObject 用于刪除對(duì)象的代碼:

I posted my solution on Django Snippets. It's based heavily on the django.db.models.query.CollectedObject code used for deleting objects:

from django.db.models.query import CollectedObjects
from django.db.models.fields.related import ForeignKey

def duplicate(obj, value, field):
    """
    Duplicate all related objects of `obj` setting
    `field` to `value`. If one of the duplicate
    objects has an FK to another duplicate object
    update that as well. Return the duplicate copy
    of `obj`.  
    """
    collected_objs = CollectedObjects()
    obj._collect_sub_objects(collected_objs)
    related_models = collected_objs.keys()
    root_obj = None
    # Traverse the related models in reverse deletion order.    
    for model in reversed(related_models):
        # Find all FKs on `model` that point to a `related_model`.
        fks = []
        for f in model._meta.fields:
            if isinstance(f, ForeignKey) and f.rel.to in related_models:
                fks.append(f)
        # Replace each `sub_obj` with a duplicate.
        sub_obj = collected_objs[model]
        for pk_val, obj in sub_obj.iteritems():
            for fk in fks:
                fk_value = getattr(obj, "%s_id" % fk.name)
                # If this FK has been duplicated then point to the duplicate.
                if fk_value in collected_objs[fk.rel.to]:
                    dupe_obj = collected_objs[fk.rel.to][fk_value]
                    setattr(obj, fk.name, dupe_obj)
            # Duplicate the object and save it.
            obj.id = None
            setattr(obj, field, value)
            obj.save()
            if root_obj is None:
                root_obj = obj
    return root_obj

對(duì)于 django >= 2 應(yīng)該有一些微小的變化.所以輸出會(huì)是這樣的:

For django >= 2 there should be some minimal changes. so the output will be like this:

def duplicate(obj, value=None, field=None, duplicate_order=None):
    """
    Duplicate all related objects of obj setting
    field to value. If one of the duplicate
    objects has an FK to another duplicate object
    update that as well. Return the duplicate copy
    of obj.
    duplicate_order is a list of models which specify how
    the duplicate objects are saved. For complex objects
    this can matter. Check to save if objects are being
    saved correctly and if not just pass in related objects
    in the order that they should be saved.
    """
    from django.db.models.deletion import Collector
    from django.db.models.fields.related import ForeignKey

    collector = Collector(using='default')
    collector.collect([obj])
    collector.sort()
    related_models = collector.data.keys()
    data_snapshot = {}
    for key in collector.data.keys():
        data_snapshot.update(
            {key: dict(zip([item.pk for item in collector.data[key]], [item for item in collector.data[key]]))})
    root_obj = None

    # Sometimes it's good enough just to save in reverse deletion order.
    if duplicate_order is None:
        duplicate_order = reversed(related_models)

    for model in duplicate_order:
        # Find all FKs on model that point to a related_model.
        fks = []
        for f in model._meta.fields:
            if isinstance(f, ForeignKey) and f.remote_field.related_model in related_models:
                fks.append(f)
        # Replace each `sub_obj` with a duplicate.
        if model not in collector.data:
            continue
        sub_objects = collector.data[model]
        for obj in sub_objects:
            for fk in fks:
                fk_value = getattr(obj, "%s_id" % fk.name)
                # If this FK has been duplicated then point to the duplicate.
                fk_rel_to = data_snapshot[fk.remote_field.related_model]
                if fk_value in fk_rel_to:
                    dupe_obj = fk_rel_to[fk_value]
                    setattr(obj, fk.name, dupe_obj)
            # Duplicate the object and save it.
            obj.id = None
            if field is not None:
                setattr(obj, field, value)
            obj.save()
            if root_obj is None:
                root_obj = obj
    return root_obj

這篇關(guān)于在 Django 中復(fù)制模型實(shí)例及其相關(guān)對(duì)象/用于遞歸復(fù)制對(duì)象的算法的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!

【網(wǎng)站聲明】本站部分內(nèi)容來(lái)源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問(wèn)題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請(qǐng)聯(lián)系我們刪除處理,感謝您的支持!

相關(guān)文檔推薦

How to draw a rectangle around a region of interest in python(如何在python中的感興趣區(qū)域周圍繪制一個(gè)矩形)
How can I detect and track people using OpenCV?(如何使用 OpenCV 檢測(cè)和跟蹤人員?)
How to apply threshold within multiple rectangular bounding boxes in an image?(如何在圖像的多個(gè)矩形邊界框中應(yīng)用閾值?)
How can I download a specific part of Coco Dataset?(如何下載 Coco Dataset 的特定部分?)
Detect image orientation angle based on text direction(根據(jù)文本方向檢測(cè)圖像方向角度)
Detect centre and angle of rectangles in an image using Opencv(使用 Opencv 檢測(cè)圖像中矩形的中心和角度)
主站蜘蛛池模板: 国产精品久久久久久久免费大片 | 日韩一区二区在线视频 | 国产韩国精品一区二区三区 | 国产精品一区二区不卡 | 最新国产视频 | 国产精久久久久久久 | 久草综合在线 | 亚洲第一免费播放区 | 人人性人人性碰国产 | 2021天天干夜夜爽 | 奇米超碰 | 亚洲激情av | 欧美日韩亚洲一区二区 | 亚洲欧美一区二区三区国产精品 | 亚洲精品日日夜夜 | 天天操天天射综合网 | 亚洲欧洲视频 | 亚洲国产精品一区二区三区 | 日一区二区 | 欧美福利 | 国产精品91视频 | 欧美日韩三级在线观看 | 中文字幕日韩欧美一区二区三区 | 国内精品一区二区 | 欧美成人精品激情在线观看 | 日韩在线免费电影 | 性做久久久久久免费观看欧美 | 一级毛片观看 | 久久久久成人精品亚洲国产 | 欧美在线一区二区三区 | 网站国产 | 亚洲欧美另类在线观看 | 精品国产18久久久久久二百 | 99爱国产 | www日本在线观看 | 国产精品一区在线观看 | 91人人看| 偷拍自拍在线观看 | 国产成人免费网站 | 中文天堂在线观看 | 美女毛片免费看 |