단일 쿼리 셋으로 데이터베이스 레코드를 선택하고 업데이트


139

두 가지 쿼리를 수행하지 않고 동일한 방법으로 updateand select문을 실행하는 방법 queryset-하나는 객체를 선택하고 하나는 객체를 업데이트합니다.

SQL에서 동등한 것은 다음과 같습니다.

update my_table set field_1 = 'some value' where pk_field = some_value

답변:


267

queryset 객체 update메소드를 사용하십시오 .

MyModel.objects.filter(pk=some_value).update(field1='some value')

95
공정한 경고입니다. update이와 같은 방법 을 사용하면 해당 모델 또는 다른 "코드 항목"에 연결된 신호가 객체에 대해 실행되지 않습니다. 화상을 입은 사람의 포인터 :)
DMac Destroyer

@DMactheDestroyer 친구 소중한 정보 주셔서 감사합니다. 그렇다면 이전 방식으로 업데이트해야합니까? (즉) 얻고 저장합니까?

@ 잘 배우고, 그것은 모두 시나리오에 달려 있습니다. 이 update방법은 대량 업데이트에는 유용하지만 사용시 수동으로 발사해야 할 수도있는 물체에 부착 된 모든 신호를 검토해야한다는 경고를 머리에 표시해야합니다.
DMac Destroyer

3
업데이트 기능에서 현재 모델 인스턴스에 액세스 할 수 있습니까? 처럼MyModel.objects.filter(pk=some_value).update(field1=self.data)
Dipak

8
@DipakChandranP 6 살짜리 질문에 의견을 남기지 말고 새로운 질문을해야합니다. 그러나 F () 표현식은 아마도 당신이 원하는 것입니다.
Daniel Roseman

70

Django 데이터베이스 객체는 객체를 생성하고 변경하기 위해 동일한 save () 메소드를 사용합니다.

obj = Product.objects.get(pk=pk)
obj.name = "some_new_value"
obj.save()

Django가 UPDATE vs. INSERT를 아는 방법
객체의 기본 키 속성이 True로 평가되는 값 (예 : None 이외의 값 또는 빈 문자열)으로 설정되면 Django는 UPDATE를 실행합니다. 객체의 기본 키 속성이 설정되어 있지 않거나 UPDATE가 업데이트하지 않은 경우, 장고는 INSERT를 실행합니다.

참조 : https://docs.djangoproject.com/en/1.9/ref/models/instances/


17

이 답변은 위의 두 가지 접근법을 비교합니다. 한 줄에 많은 객체를 업데이트하려면 다음을 수행하십시오.

# Approach 1
MyModel.objects.filter(field1='Computer').update(field2='cool')

그렇지 않으면 쿼리 세트를 반복하고 개별 객체를 업데이트해야합니다.

#Approach 2    
objects = MyModel.objects.filter(field1='Computer')
for obj in objects:
    obj.field2 = 'cool'
    obj.save()
  1. 접근법 1은 'n + 1'데이터베이스 쿼리를 만드는 접근법 2에 비해 하나의 데이터베이스 쿼리 만하기 때문에 더 빠릅니다. (쿼리 세트의 n 개 항목의 경우)

  2. 주먹 접근법은 하나의 db 쿼리, 즉 UPDATE를 만들고 두 번째 방법은 SELECT와 UPDATE를 만듭니다.

  3. 단점은 업데이트 updated_on또는 이와 관련된 필드와 같은 트리거가 있다고 가정하면 직접 업데이트 즉, 접근 1에서는 트리거되지 않는다는 것입니다.

  4. 접근법 1은 쿼리 셋에서 사용되므로 접근법 2의 경우가 아니라 한 번에 여러 객체를 업데이트 할 수 있습니다.


1과 관련하여-쿼리 결과는 첫 번째 쿼리 호출에서 캐시되므로 실제로 DB에 대한 단일 호출이 여전히 있습니다.
user2340939

2

serializer사물 의 경우에만 매우 간단한 방법으로 업데이트 할 수 있습니다!

my_model_serializer = MyModelSerializer(
    instance=my_model, data=validated_data)
if my_model_serializer.is_valid():

    my_model_serializer.save()

form사물 의 경우에만 !

instance = get_object_or_404(MyModel, id=id)
form = MyForm(request.POST or None, instance=instance)
if form.is_valid():
    form.save()

나는 serializer가 Djanog Rest Framework에서 왔으며 장고가 아니라고 생각합니다.
코드 견습생

1
예, 그러나 Django formDjango Proper에서 왔습니다.
Jamil Noyda
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.