2013-03-18 1 views
7

장고 앱에는 사용자의 다양한 구성 옵션을 포함하는 StaffSettings라는 장고 모델이 있습니다. 각 사용자는 StaffSettings 테이블에 최대 하나의 항목 만 있습니다. , 나는 그것이 일반적인 사용 사례처럼 보이기 때문에 하나 개의 라인에 맞게 기능의 몸을 선호get_or_create 그리고 나서 장고에서 객체를 업데이트하는 관용적 인 방법이 있습니까?

def set_default_year_level(u, year_level): 
    obj, _created = StaffSettings.objects.get_or_create(user=u) 
    obj.default_year_level = year_level 
    obj.save() 

:

한 설정이 default_year_level이라고 가정하고, 내 사용자가 같은 객체를 위해 나는 코드가 하지만 난

해당 사용자가 이미 StaffSettings 테이블의 행이있는 경우 잘 작동
def set_default_year_level(u, year_level): 
    StaffSettings.objects.filter(user=u).update(default_year_level=year_level) 

로 정의하지만, 존재하지 않는 경우는 관련 행을 작성하지 않을 경우.

코드를 작성하는 관용적/최선의 방법은 무엇입니까? (예 : 일종의 filter_or_create 함수가 있습니까? 아니면 다른 사람들이이 관용구를 처리하기 위해 데코레이터/도우미 함수를 작성합니까?)

답변

5

첫 번째 함수에는 아무런 문제가 없습니다. . 당신이 모델의 필드의 많은에서 같은 기능을 필요로하고 자신을 반복하지 않으려면

그러나 당신은 매개 변수로 필드를 전달할 수 있습니다

def set_default_value(u, field, value): 
    obj, _created = StaffSettings.objects.get_or_create(user=u) 
    setattr(obj, field, value) 
    obj.save() 

그리고 나는 멀리합니다 이 기능을 한 번에 여러 개체를 업데이트하는 것을 의미하고 모델에 저장() 메소드도 신호를 트리거하지 않습니다 어쨌든로 갱신() 기능

+0

update()의 결함을 언급 해 주셔서 감사합니다. 나는 그것을 한 번 읽었지만 잊어 버린 것 같아요. 나는 당신이 제안한 것과 비슷한 것을했지만 set_default_values ​​(u, ** kwargs)를 만들어 필드에 문자열을 전달할 필요가 없도록 대신 set_default_values ​​(u, default_year_level = year_level)와 같은 코드를 작성할 수있다. . – bryn

2

장고 1.7 이후는 update_or_create()을 사용할 수 있습니다 (https://docs.djangoproject.com/en/dev/topics/db/queries/#updating-multiple-objects-at-once 참조)

def set_default_year_level(u, year_level): 
    obj, _created = StaffSettings.objects.update_or_create(
     user=u, 
     default_year_level=year_level 
    ) 

또는 이전의 대답에 설명 된대로 더 일반적인 경우에 대한 :

def set_default_values(u, **kwargs): 
    obj, _created = StaffSettings.objects.update_or_create(user=u, defaults=kwargs) 

또한 추가 요구 사항을 달성 나는에 맞게 기능의 몸을 선호

한 줄