IT

Django unique_together 쓰지마세요~

bepuri 2020. 11. 6. 09:38
728x90

update시에는 validation check를 create시와 다르게 해야됩니다.

stackoverflow.com/questions/31646452/unique-together-is-not-allowing-to-update-record

 

unique_together is not allowing to update record

I am working on implemeting Like/Unlike feature in API for mobile app via Django Rest Framework. So I have following model: class PlaylistLikes(models.Model): user = models.ForeignKey(User)

stackoverflow.com

 

예를들면 위 스택오버플로 예시처럼

class PlaylistLikes(models.Model):
    user = models.ForeignKey(User)
    playlist = models.ForeignKey(Playlist)
    like = models.BooleanField(default=0, blank=True)

    class Meta:
        unique_together = ('user', 'playlist',)
        verbose_name = "Playlist like"
        verbose_name_plural = "Playlist likes"

이와 같은 모델 코드가 있다고 가정해봅시다.

이 경우에 POST와 PUT은 다르게 처리되야되는게 맞습니다.

POST는 unique_together로 해당 unique_together로 만들어진 결과값이 기존에 존재하면 데이터가 추가로 생성되면 안되고 오류가 나야되는게 맞습니다.

 

하지만 PUT , 업데이트의 경우 플레이 리스트의 id로 해당 플레이리스트의 특정 내용만 변경해야하는 경우가 있을수도 있어요. 그 경우에는 변경된 사항만 해당 플레이 리스트에 업데이트 해줘야하는게 맞으나 아래처럼 unique set이 아니라고 에러가 떠버립니다.

 

{ "non_field_errors": [ "The fields foo_a, foo_b must make a unique set." ] }

 

결론적으로

self._validated_data = self.run_validation(self.initial_data)

해당 코드를 is_valid함수에서 실행하는 시점에 에러가뜨고, initial_data의 유효성 검사 자체를 통과 못하는 문제가 생겼습니다. update면 해당 row를 업데이트할 수도 있는건데, 그게 애초에 불가능한겁니다.

 

stackoverflow를 참고해서 해결하려고 여러번 시도했으나 번번히 실패가 되더라구요.

한참 헤매다가 unique_together가 deprecated 예정인 기능이라는걸 알게 됐고,

https://docs.djangoproject.com/en/3.1/ref/models/constraints/#uniqueconstraint

UniqueConstraint가 생겼더라구요.

unique_together 대신 해당 기능을 사용하니 정상적으로 update가 됩니다.

 

결론. unique_together 쓰지말고 UniqueConstraint 쓰세요.

728x90