Django 모델 인스턴스 개체를 복제하여 데이터베이스에 저장하려면 어떻게 해야 합니까?
Foo.objects.get(pk="foo")
<Foo: test>
데이터베이스에 위의 오브젝트를 복사한 다른 오브젝트를 추가하고 싶습니다.
내 테이블에 열이 하나 있다고 가정해봐.첫 번째 행 개체를 다른 기본 키로 다른 행에 삽입하려고 합니다.내가 어떻게 그럴 수 있을까?
오브젝트의 프라이머리 키를 변경하고 save()를 실행합니다.
obj = Foo.objects.get(pk=<some_existing_pk>)
obj.pk = None
obj.save()
키를 자동으로 생성하는 경우 새 키를 없음으로 설정합니다.
업데이트/삽입에 대한 자세한 내용은 여기를 참조하십시오.
모델 인스턴스 복사에 관한 공식 문서:https://docs.djangoproject.com/en/2.2/topics/db/queries/ #syslog-model-syslog
데이터베이스 쿼리용 Django 문서에는 모델 인스턴스 복사에 대한 섹션이 포함되어 있습니다.프라이머리 키가 자동 생성되었다고 가정하고 복사할 오브젝트를 입수하여 프라이머리 키를 다음과 같이 설정합니다.None
츠키다
blog = Blog(name='My blog', tagline='Blogging is easy')
blog.save() # blog.pk == 1
blog.pk = None
blog.save() # blog.pk == 2
첫 "" " " "''입니다.save()
오브젝트가 두 오브젝트가 생성됩니다.save()
복사가 생성됩니다.
매뉴얼을 계속 읽다 보면 (1) 모델 서브클래스의 인스턴스인 오브젝트 복사와 (2) 다대다 관계 오브젝트를 포함한 관련 오브젝트 복사라는 두 가지 복잡한 경우의 처리 방법에 대한 예도 있습니다.
에 대한 : 를 miah로 합니다.None
miah의 .그래서 저는 그 방법을 장고가 추천하는 방법이라고 주로 강조하고 있습니다.
이력 메모:이것은 버전 1.4까지 장고 문서에서 설명되지 않았다.하지만 1.4 이전부터 가능했습니다.
향후 사용 가능한 기능:이 티켓에서 앞서 언급한 문서 변경이 이루어졌습니다.티켓의 댓글 스레드에서는 빌트인 추가에 대한 논의도 있었습니다.copy
모델 클래스에서는 기능하고 있습니다만, 아직 그 문제에 대처하지 않기로 결정한 것으로 알고 있습니다.따라서 현재로서는 이 "수동" 복사 방식을 사용해야 합니다.
여기서 조심해요.어떤 종류의 루프에 속해 있고 개체를 하나씩 검색하는 경우 이 작업은 매우 비용이 많이 들 수 있습니다.데이터베이스에 콜을 송신하지 않는 경우는, 다음의 조작을 실시합니다.
from copy import deepcopy
new_instance = deepcopy(object_you_want_copied)
new_instance.id = None
new_instance.save()
다른 응답과 동일한 작업을 수행하지만 개체를 검색하기 위한 데이터베이스 호출은 수행되지 않습니다.데이터베이스에 아직 존재하지 않는 오브젝트의 복사본을 작성하려는 경우에도 유용합니다.
다음 코드를 사용합니다.
from django.forms import model_to_dict
instance = Some.objects.get(slug='something')
kwargs = model_to_dict(instance, exclude=['id'])
new_instance = Some.objects.create(**kwargs)
여기 클론 스니펫이 있습니다.클론 스니펫을 모델에 추가하여 다음과 같이 할 수 있습니다.
def clone(self):
new_kwargs = dict([(fld.name, getattr(old, fld.name)) for fld in old._meta.fields if fld.name != old._meta.pk]);
return self.__class__.objects.create(**new_kwargs)
이를 수행하는 방법은 Django1.4의 공식 Django 문서에 추가되었습니다.
https://docs.djangoproject.com/en/1.10/topics/db/queries/ #syslog-model-syslog
공식적인 답변은 Miah의 답변과 비슷하지만, 의사들은 상속과 관련된 물건에 대해 몇 가지 어려움을 지적하고 있기 때문에, 여러분은 그 문서를 꼭 읽어야 할 것입니다.
나는 받아들여진 답을 가진 몇 명의 고추를 우연히 만났다.제 해결책은 이렇습니다.
import copy
def clone(instance):
cloned = copy.copy(instance) # don't alter original instance
cloned.pk = None
try:
delattr(cloned, '_prefetched_objects_cache')
except AttributeError:
pass
return cloned
주의: 이것은 Django 문서에서 공식적으로 승인되지 않은 솔루션을 사용하며, 향후 버전에서는 더 이상 작동하지 않을 수 있습니다.이것을 1.9.13에서 테스트했습니다.
계속 할 수 입니다.copy.copy
인스턴스를 재사용할 생각이 없는 경우에도 복제 중인 인스턴스가 함수의 인수로 전달된 경우 이 단계를 수행하는 것이 더 안전할 수 있습니다.그렇지 않으면 함수가 반환될 때 발신자는 예기치 않게 다른 인스턴스를 갖게 됩니다.
copy.copy
원하는 방식으로 Django 모델 인스턴스의 얕은 복사본을 생성하는 것 같습니다.이것은 문서화되어 있지 않은 것 중 하나입니다만, 산세척과 산세척으로 동작하기 때문에 충분히 서포트되고 있을 것입니다.
둘째, 승인된 답변은 사전 추출된 결과를 새 인스턴스에 첨부한 상태로 남습니다.이러한 결과는 명시적으로 대 다 관계를 복사하지 않는 한 새 인스턴스와 연관지을 수 없습니다.미리 검색된 관계를 이동할 경우 데이터베이스와 일치하지 않는 결과가 나타납니다.프리페치를 추가할 때 작업 코드를 깨는 것은 불쾌한 일이 될 수 있습니다.
중_prefetched_objects_cache
모든 프리페치를 빠르게 제거할 수 있습니다.후속 투 다 액세스는 프리페치가 없었던 것처럼 동작합니다.언더스코어로 시작하는 문서화되어 있지 않은 속성을 사용하는 것은 호환성 문제를 요구하는 것일 수 있지만 현재로서는 문제가 없습니다.
pk를 없음으로 설정하는 것이 좋습니다.sinse Django는 올바르게 pk를 생성할 수 있습니다.
object_copy = MyObject.objects.get(pk=...)
object_copy.pk = None
object_copy.save()
이는 모델 인스턴스를 복제하는 또 다른 방법입니다.
d = Foo.objects.filter(pk=1).values().first()
d.update({'id': None})
duplicate = Foo.objects.create(**d)
이것에 의해, 개별적으로 변환 가능한 메모리내 카피가 실행됩니다.
original = CheckoutItem(title="test", ...)
copy = CheckoutItem()
for f in CheckoutItem._meta.fields:
setattr(copy, f.attname, getattr(original, f.attname))
또는 방법으로서:
def clone(self):
"""Returns a clone of this instance."""
clone = self.__class__()
for f in self.__class__._meta.fields:
setattr(clone, f.attname, getattr(self, f.attname))
return clone
여러 상속 수준(예: >= 2, 또는 아래의 모델 C)을 가진 모델을 복제하려면
class ModelA(models.Model):
info1 = models.CharField(max_length=64)
class ModelB(ModelA):
info2 = models.CharField(max_length=64)
class ModelC(ModelB):
info3 = models.CharField(max_length=64)
여기 질문을 참조해 주세요.
이거 드셔보세요
original_object = Foo.objects.get(pk="foo")
v = vars(original_object)
v.pop("pk")
new_object = Foo(**v)
new_object.save()
django 관리 사이트 내에 UI를 작성하는 패키지가 있습니다.https://github.com/RealGeeks/django-modelclone
pip install django-modelclone
INSTALLED_에 "모델 클론" 추가APPS 및 admin.py로 Import합니다.
그런 다음 모델을 클로닝할 수 있도록 하려면 "admin"을 바꿉니다.지정된 관리 모델 클래스 "modelclone"의 ModelAdmin"입니다.Clonable Model Admin"을 클릭합니다.그러면 해당 모델의 인스턴스 세부 정보 페이지에 "복제" 버튼이 나타납니다.
를 가지고 있는 경우OneToOneField
다음 방법으로 해야 합니다.
tmp = Foo.objects.get(pk=1)
tmp.pk = None
tmp.id = None
instance = tmp
이 간단한 프로세스로 문제없이 동작합니다.
foo_obj = Foo.objects.get(pk="foo")
foo_values = foo_obj.__dict__
foo_values.pop('_state')
foo_values.pop('id')
foo_new_obj = Foo(**foo_values)
foo_new_obj.save()
언급URL : https://stackoverflow.com/questions/4733609/how-do-i-clone-a-django-model-instance-object-and-save-it-to-the-database
'programing' 카테고리의 다른 글
두 MySQL 데이터베이스 비교 (0) | 2022.10.25 |
---|---|
Vue에서 비동기 데이터를 저장하는 가장 좋은 방법은 무엇입니까? (0) | 2022.10.25 |
Master와 Slave의 데이터베이스가 다른 경우 Mysql DB를 다시 동기화하려면 어떻게 해야 합니까? (0) | 2022.10.25 |
main은 유효한 Java 식별자입니까? (0) | 2022.10.25 |
Oracle에서 MariaDB에서 쿼리 실행 (0) | 2022.10.25 |