https://django-orm-cookbook-ko.readthedocs.io/en/latest/copy.html
2. 기존에 저장된 행을 복사해 새로 저장하는 방법은 무엇인가요? — Django ORM Cookbook 2.0 documentation
2. 기존에 저장된 행을 복사해 새로 저장하는 방법은 무엇인가요? 장고 ORM에는 모델 인스턴스를 복사하는 내장 메서드가 없습니다. 하지만 모든 필드의 값을 복사하여 새 인스턴스를 만들고 새
django-orm-cookbook-ko.readthedocs.io
save 와 create
save 는 조회(인스턴스 생성)후, 저장
create 는 바로 만들어.
레코드 복사
장고 ORM에는 모델 인스턴스를 복사하는 내장 메서드가 없습니다. 하지만 모든 필드의 값을 복사하여 새 인스턴스를 만들고 새로 저장하는 것은 어렵지 않습니다.
모델 인스턴스를 저장할 때, pk 필드 값이 None 으로 지정되어 있으면 데이터베이스에 새 행으로 저장됩니다. pk 외의 모든 필드 값은 그대로 복제됩니다.
In [2]: Hero.objects.all().count()
Out[2]: 4
In [3]: hero = Hero.objects.first()
In [4]: hero.pk = None
In [5]: hero.save()
In [6]: Hero.objects.all().count()
Out[6]: 5
반복문으로 처리
요런 느낌?
for object in (Iti.objects.all()):
object.tour_item_id = 포린키값
object.save()
for index, objet in enumerate(BibleKorhrv.objects.all()):
object.fake_id = index + 1
object.save()레코드 신규
## bulk_create
>>> Category.objects.all().count()
2
>>> Category.objects.bulk_create(
[Category(name="God"),
Category(name="Demi God"),
Category(name="Mortal")]
)
[<Category: God>, <Category: Demi God>, <Category: Mortal>]
>>> Category.objects.all().count()
5
이미 생성된 object들을 동일하게 복사해 생성시켜야 할 때가 있습니다.
Django 공식 문서를 참고해서 해결 해 보겠습니다.
가장 기본적인 방법은, 해당 object의 pk를 None으로 설정하는 방법입니다.
blog = Blog(name='My blog', tagline='Blogging is easy')
blog.save() # blog.pk == 1
blog.pk = None
blog.save() # blog.pk == 2
해당 pk가 None으로 설정된 instance는 DB에 새로운 레코드로 생성되며, pk를 제외한 나머지 모든 필드는 기존의 값이 복사됩니다.
이번에는 상속된 model을 clone하는 방법입니다.
class ThemeBlog(Blog):
theme = models.CharField(max_length=200)
django_blog = ThemeBlog(name='Django', tagline='Django is easy', theme='python')
django_blog.save() # django_blog.pk == 3
django_blog.pk = None
django_blog.id = None
django_blog.save() # django_blog.pk == 4
pk와 함께 id 또한 None으로 설정해야 합니다.
단, 위와 같은 방법은 DB table에 존재하지 않는, relation들은 복사하지 않습니다.
Entry가 ManyToManyField로 Author를 가지고 있다고 해 봅시다.
entry = Entry.objects.all()[0] # some previous entry
old_authors = entry.authors.all()
entry.pk = None
entry.save()
entry.authors.set(old_authors)
위와 같이 이전의 author들을 명시적으로 복사해 주는 구문이 필요하게 됩니다.
OneToOneField일 경우, one-to-one unique constraint를 피하기 위해 연관된 객체를 복제해서 대입해 주어야 합니다.
detail = EntryDetail.objects.all()[0]
detail.pk = None
detail.entry = entry
detail.save()
entry를 미리 복제한 후, 위처럼 대입해 주면 됩니다.
instancesdocs.djangoproject.com/en/3.1/topics/db/queries/#copying-model-instances
Making queries | Django documentation | Django
Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate
docs.djangoproject.com
update_or_create는 장고에서 제공하는 메서드로 get_or_create와 비슷하게 작동한다.
객체가 이미 존재하는 경우 update 하고 없는 경우 create하는 것이다.
get_or_create와 마찬가지로 (object, created) 튜플을 반환한다.
object는 update되거나 create되는 객체이고 created는 boolean으로 객체가 create되면 True, 이미 있다면 False로 반환된다.
경쟁조건을 피하기 위해 get_or_create와 마찬가지로 defaults 파라미터를 활용할 수 있다.
defaults = {'first_name': 'Bob'}
try:
obj = Person.objects.get(first_name='John', last_name='Lennon')
for key, value in defaults.items():
setattr(obj, key, value)
obj.save()
except Person.DoesNotExist:
new_values = {'first_name': 'John', 'last_name': 'Lennon'}
new_values.update(defaults)
obj = Person(**new_values)
obj.save()
# 위 코드와 같은 결과가 나오는 update_or_create
obj, created = Person.objects.update_or_create(
first_name='John', last_name='Lennon',
defaults={'first_name': 'Bob'},
)
출처: https://docs.djangoproject.com/en/4.0/ref/models/querysets/#update-or-create
Django
The web framework for perfectionists with deadlines.
docs.djangoproject.com
bulk_update
from django.db import models
class Person(models.Model):
username = models.CharField(max_length = 200, unique = True)
firstName = models.CharField(max_length = 200)
middleName = models.CharField(max_length = 200)
lastName = models.CharField(max_length = 200)
age = models.IntegerField(default = 0)
people = Person.objects.all()
for person in people:
person.age += 1
Person.objects.bulk_update(people, update_fields = ['age'])
bulk update는 인자값으로 fields 지정 필수.
Person.objects.save(people) 하면 오래걸린다 머 그거지.
bulk_update()메소드를 사용하여 인스턴스의 기본 키를 업데이트 할 수 없습니다.
다.
아래 코드에서 some_models =[] 에는 필드값이 업데이트된 Some_Model의 QuerySet 객체가 들어있다고 보면 된다.
Some_Model.objects.bulk_update(
some_models,
batch_size=3000,
fields=["status", "result"],
)
'erp 도전' 카테고리의 다른 글
상품 복사 구현 1)js전체선택, 폼 인풋 리스트 가져오기, 날짜(듀프,요일 체크) (0) | 2023.05.01 |
---|---|
주화입마에 빠져서, 기본기 다지기를 병행하기로 (0) | 2023.04.28 |
dispatch 메서드: self.get_object() , self.object (1) | 2023.04.27 |
일정표 구현 4) 수정/삭제 (0) | 2023.04.26 |
장고 마이그레이션 에러 / 복구 showmigrations (0) | 2023.04.26 |
일정표 구현 3: 조/중/석 구분값으로 저장, 사용하기 (0) | 2023.04.25 |
일정표 구현2) : 공유 일정표와 개별 일정표 구현 (0) | 2023.04.24 |
일정표 구현 1) tinymce (0) | 2023.04.24 |
댓글