programing

장고에서 단일 쿼리 세트로 레코드를 선택하고 업데이트하는 방법은 무엇입니까?

skycolor 2023. 8. 10. 18:38
반응형

장고에서 단일 쿼리 세트로 레코드를 선택하고 업데이트하는 방법은 무엇입니까?

실행 방법update그리고.select같은 내용의 진술queryset두 가지 쿼리를 수행해야 하는 대신 하나는 개체를 선택하고 다른 하나는 개체를 업데이트합니다.

SQL에 해당하는 것은 다음과 같습니다.

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

쿼리 집합 개체 메서드를 사용합니다.

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

장고 데이터베이스 개체는 개체를 만들고 변경하는 데 동일한 저장() 방법을 사용합니다.

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

장고가 업데이트하는 방법과삽입
개체의 기본 키 특성이 True로 평가되는 값(예: 없음 또는 빈 문자열 이외의 값)으로 설정된 경우 Django는 UPDATE를 실행합니다.개체의 기본 키 속성이 설정되지 않았거나 업데이트가 아무것도 업데이트하지 않은 경우 Django는 INSERT를 실행합니다.

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

이 답변은 위의 두 가지 접근 방식을 비교합니다.여러 개체를 한 줄로 업데이트하려면 다음 작업을 수행합니다.

# 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로 만들고, 두 번째 접근 방식은 두 가지를 만듭니다: 선택한 다음 UPDATE.

  3. 단점은 업데이트와 같은 트리거가 있다고 가정할 때updated_on또는 이러한 관련 필드는 직접 업데이트 접근 1에서 트리거되지 않습니다.

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

첫 번째 방법

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

두 번째 방법

q = MyModel.objects.get(pk=some_value)
q.field1 = 'some value'
q.save()

세 번째 방법

을 사용하여get_object_or_404

q = get_object_or_404(MyModel,pk=some_value)
q.field1 = 'some value'
q.save()

네 번째 방법

필요하다면pk=some_value그때 존재하는update그렇지 않으면create을 사용하여 새것update_or_create.

MyModel.objects.update_or_create(pk=some_value,defaults={'field1':'some value'})

이전 필드 값을 기준으로 새 값을 설정해야 하는 경우 다음과 같은 작업을 수행합니다.

update my_table set field_1 = field_1 + 1 where pk_field = some_value

쿼리 표현식 사용:

MyModel.objects.filter(pk=some_value).update(field1=F('field1') + 1)

이렇게 하면 먼저 읽지 않고 데이터베이스에 대한 하나의 업데이트 요청을 사용하는 업데이트가 자동으로 실행됩니다.

의 경우에만.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()

허용된 답변은 효과적이지만 원치 않는 부작용이 있습니다.

예를 들어 imageField를 사용하는 경우 업데이트()는 작동하고 다른 데이터는 업데이트하지만 imageField 데이터는 업데이트하지 않습니다.

class ProfileSetting(models.Model):

    first_name = models.CharField(blank=True)

    logo = models.ImageField(blank=True, null=True, upload_to="profile/logo/")

update_data = {
  "first_name": "john",
  "logo": request.FILES['logo'] # logo will not be properly update
}

ProfileSetting.objects.filter(pk=some_value).update(**update_data)

다음은 update() 메서드가 사용될 Django ImageField가 업데이트되지 않는 몇 가지 예입니다.

위에서 언급한 답변은 효과적이지만 원치 않는 부작용이 발생하므로 이러한 오류를 방지하기 위해 예외 블록에 DB 코드를 기록합니다.

    try:
        obj = <Your_Model_Name>.objects.get(PK=<pk_id>)
        obj.name = req.POST.get("name")
        obj.save()
    except Exception as e:
        print(e)

언급URL : https://stackoverflow.com/questions/2712682/how-to-select-a-record-and-update-it-with-a-single-queryset-in-django

반응형