Django 모델에서 두 개의 필드를 "고유" 조합으로 정의하는 방법
Django 모델에서 두 개의 필드를 "고유" 조합으로 정의하는 방법
예를 들어, User
모델에서 username
과 email
필드를 함께 고유하게 지정하려면 다음과 같이 코드를 작성해야 합니다.
from django.db import models
class User(models.Model):
username = models.CharField(max_length=255, unique=False)
email = models.EmailField(max_length=255, unique=False)
class Meta:
unique_together = ('username', 'email',)
위 코드에서 unique_together
튜플에 username
과 email
필드를 지정하면, 동일한 username
과 email
조합을 가진 두 개 이상의 사용자 레코드를 생성할 수 없습니다.
참고:
unique_together
속성은unique=True
속성과 함께 사용할 수 없습니다.unique_together
속성은 여러 개의 필드 그룹을 정의하는 데 사용할 수 있습니다. 예를 들어 다음과 같이 코드를 작성하여first_name
과last_name
필드,city
와state
필드를 함께 고유하게 지정할 수 있습니다.
class Person(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
city = models.CharField(max_length=255)
state = models.CharField(max_length=2)
class Meta:
unique_together = (('first_name', 'last_name'), ('city', 'state'),)
unique_together
속성은 데이터베이스 백엔드에 따라 다르게 작동할 수 있습니다. 자세한 내용은 Django 문서를 참조하십시오.
Django 모델에서 두 개의 필드를 "고유" 조합으로 정의하는 예제 코드
다음은 username
과 email
필드를 함께 고유하게 지정하는 User
모델의 예제입니다.
from django.db import models
class User(models.Model):
username = models.CharField(max_length=255)
email = models.EmailField(max_length=255)
class Meta:
unique_together = ('username', 'email',)
개인 모델
다음은 first_name
과 last_name
필드, city
와 state
필드를 함께 고유하게 지정하는 Person
모델의 예제입니다.
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
city = models.CharField(max_length=255)
state = models.CharField(max_length=2)
class Meta:
unique_together = (('first_name', 'last_name'), ('city', 'state'),)
사용법
위 모델을 사용하여 다음과 같이 사용자 인스턴스를 생성할 수 있습니다.
user1 = User.objects.create(username="alice", email="[email protected]")
user2 = User.objects.create(username="bob", email="[email protected]")
user3 = User.objects.create(username="alice", email="[email protected]") # 오류 발생
위 코드에서 user1
과 user2
는 성공적으로 생성되지만 user3
는 생성되지 않습니다. 이는 username
과 email
필드의 값이 user1
과 동일하기 때문입니다.
또한 다음과 같이 Person
인스턴스를 생성할 수 있습니다.
person1 = Person.objects.create(first_name="John", last_name="Doe", city="New York", state="NY")
person2 = Person.objects.create(first_name="Jane", last_name="Doe", city="New York", state="NY")
person3 = Person.objects.create(first_name="John", last_name="Smith", city="New York", state="NY")
person4 = Person.objects.create(first_name="Jane", last_name="Doe", city="Chicago", state="IL")
# person1, person2, person3, person4 모두 성공적으로 생성됩니다.
위 코드에서 person1
, person2
, person3
은 first_name
과 last_name
필드의 값이 동일하지만 city
또는 state
필드의 값이 다르기 때문에 성공적으로 생성됩니다.
- 위 코드는 예시이며 실제 프로젝트에서는 상황에 맞게 모델을 정의해야 합니다.
Django 모델에서 두 개의 필드를 "고유" 조합으로 정의하는 대체 방법
unique_together
속성을 사용하지 않고 커스텀 유효성 검사자를 사용하여 두 개의 필드를 함께 고유하게 지정할 수도 있습니다.
from django.core.exceptions import ValidationError
from django.db import models
def validate_unique_username_email(value):
username, email = value
if User.objects.filter(username=username, email=email).exists():
raise ValidationError("사용자 이름과 이메일 조합이 이미 존재합니다.")
class User(models.Model):
username = models.CharField(max_length=255, validators=[validate_unique_username_email])
email = models.EmailField(max_length=255, validators=[validate_unique_username_email])
위 코드에서 validate_unique_username_email
함수는 username
과 email
값을 받아 데이터베이스에 동일한 값을 가진 레코드가 있는지 확인합니다. 만약 동일한 레코드가 존재하면 ValidationError
예외를 발생시켜 모델 유효성 검사를 실패시킵니다.
신호 사용
신호를 사용하여 모델 저장 시점에 두 개의 필드 값을 검사하고 동일한 값을 가진 레코드가 존재하는 경우 저장을 취소하는 방법도 있습니다.
from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.core.exceptions import ValidationError
@receiver(pre_save, sender=User)
def validate_unique_username_email(sender, instance, **kwargs):
if User.objects.filter(username=instance.username, email=instance.email).exclude(pk=instance.pk).exists():
raise ValidationError("사용자 이름과 이메일 조합이 이미 존재합니다.")
위 코드에서 validate_unique_username_email
함수는 pre_save
신호를 수신하고 User
모델 인스턴스가 저장되기 전에 username
과 email
값을 검사합니다. 만약 동일한 값을 가진 레코드가 존재하면 ValidationError
예외를 발생시켜 모델 저장을 취소합니다.
장단점 비교
방법 | 장점 | 단점 |
---|---|---|
unique_together 속성 | 간결하고 사용하기 쉬움 | 데이터베이스 백엔드에 따라 다르게 작동할 수 있음 |
커스텀 유효성 검사자 | 더 많은 제어 가능성 | 코드가 더 복잡해짐 |
신호 | 유연성이 높음 | 코드가 더 복잡해짐 |
선택 기준
- 간결하고 사용하기 쉬운 방법을 원한다면
unique_together
속성을 사용하는 것이 좋습니다. - 더 많은 제어 가능성이 필요하거나 특정한 유효성 검사 로직을 구현해야 하는 경우 커스텀 유효성 검사자를 사용하는 것이 좋습니다.
- 모델 저장 시점에 추가적인 처리를 수행해야 하는 경우 신호를 사용하는 것이 좋습니다.
unique_together
속성, 커스텀 유효성 검사자, 신호에 대한 자세한 내용은 Django 문서를 참조하십시오.
django django-models