Django 모델 레이어의 필드 관계(일대일, 다대일, 다대다)
django
유지보수표 관계의 방식이다.그 중에서 주로 일대일, 다대일 및 다대다on_delete
속성은 관련 데이터가 삭제되었을 때의 조작을 설명하는데 다음과 같다models.PROTECT: 연결된 데이터를 삭제하여 ProtectedError 오류 발생
models.SET_NULL: 연관된 값이 null로 설정됩니다. 사전 요구 사항은 FK 필드가 비어 있어야 합니다.
models.SET_DEFAULT: 연관된 데이터를 삭제하고 연관된 값을 기본값으로 설정합니다. FK 필드는 기본값을 설정해야 합니다.
models.DO_NOTHING: 연결된 데이터를 삭제하고 아무것도 하지 않음
일대일 관계
모델류는
OneToOneField
를 사용하여 일대일 관계를 정의한다.예를 들어 선생님표를 가지고 있을 때 바로 교수표가 필요하다. 그러면 교수표는 선생님표의 일련의 속성을 가지고 있을 수 있다. 그러면 선생님표의 필드를 교수표로 직접 복제하고 싶지 않다. 그러면
OnToOneField
를 통해 교수표를 계승할 수 있다.사실 모델 클래스 상속을 사용할 때도 일대일 관계가 포함되어 있다
OneToOneField(to, on_delete, parent_link=False, options)
class Teacher(models.Model):
name = models.CharField(max_length=50)
age = models.CharField(max_length=50)
def __str__(self):
return self.name
class Professor(models.Model):
teacher = models.OneToOneField(Teacher,primary_key=True,on_delete=models.CASCADE)
big_project = models.CharField(max_length=50)
def __str__(self):
return self.teacher.name
manage.py shell
에서 데이터베이스 작업 수행>>> t1 = Teacher.objects.create(name='Jack',age='22')
>>> t2 = Teacher.objects.create(name='Bob',age='17')
>>> p1 = Professor.objects.create(teacher=t1,big_project=' ')
>>> p1.teacher
<Teacher: Jack>
>>> p1.teacher = t2
>>> p1.save()
>>> p1.teacher
<Teacher: Bob>
위의 테스트에서 p1에 대응하는 교수를 Bob로 변신시킨 것 같다.
그러나 데이터베이스에 이전에 t1선생님이 대응한 교수 정보가 존재했다. 이때의 값 부여 조작은 교수님을 가르치기 전의 교수 데이터를 덮어쓰지 않고 값은 다시 만들어졌다.
올바른 방법은 데이터의 일대일 관계를
delete
관계를 통해 삭제한 다음에 다시 부여하는 것이다다대일 관계
Django
사용django.db.models.ForeignKey
으로 다대일 관계를 정의한다.ForeignKey
위치 매개 변수가 필요합니다: 이 모델과 관련된 클래스생활 속의 다대일 관계: 담임선생님, 반 관계.담임 선생님은 많은 반을 이끌 수 있지만, 각 반에는 담임 선생님이 한 분만 있을 수 있다
class Headmaster(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Class(models.Model):
class_name = models.CharField(max_length=50)
teacher = models.ForeignKey(Headmaster,null=True,on_delete=models.SET_NULL)
def __str__(self):
return self.class_name
>>> H1 = Headmaster(name=' ')
>>> H1.save()
>>> H1
<Headmaster: >
>>> H2 = Headmaster(name=' ')
>>> H2.save()
>>> Headmaster.objects.all()
[<Headmaster: >, <Headmaster: >]
이상에서 두 개의 선생님 데이터를 만들었습니다.
저희가 외부 키 연결을 비워둘 수 있기 때문에
null=True
학급표를 만들 때 직접 저장할 수 있고 선생님 데이터를 제공할 필요가 없습니다.>>>C1 = Class(class_name=' ')
>>>C2 = Class(class_name=' ')
# ,
# IntegrityError: NOT NULL constraint failed: bbs_class.teacher_id
>>>C1.teacher = H1
>>>C2.teacher = H2
>>>C1.save()
>>>C2.save()
선생님을 한 학급으로 분배한 후, 학급표에 선생님 필드가 연결되어 있기 때문에, 우리는 학급을 통해 대응하는 선생님을 찾을 수 있다
선생님 표에는 관련 학급 필드가 없지만 선생님을 통해 그가 가지고 있는 학급을 찾을 수 있다. 이런 조회 방식을 관련 조회라고도 부른다.
모델 클래스 이름을 통해 '' 추가set, 역방향 검색을 실현합니다
>>> H1.class_set.all()
<QuerySet [<Class: >]>
우리 는 다대일 의 관계 이기 때문 에, 우리 선생님 이 여러 반 에 대응할 수 있다는 것 을 설명한다
우리는 계속해서 H1 선생님께 새로운 반을 배정할 수 있다
>>> C3 = Class(class_name=' ')
>>> C3.teacher = H1
>>> C3.save()
>>> H1.class_set.all()
[<Class: >, <Class: >]
한 반은 한 선생님만 대응할 수 있습니다. 외부 키는 유일합니다. 그러면 C1반에 새로운 선생님을 계속 배정할 때 이전의 선생님 정보를 덮어쓰고 새로운 선생님을 저장하지 않습니다.
>>> H3 = Headmaster(name=' ')
>>> H3.save()
>>> C1.teacher
<Headmaster: >
>>> C1.teacher=H3
>>> C1.save()
>>> C1.teacher
<Headmaster: >
이 반의 선생님을 삭제합니다. 키 필드가 설정되어 있기 때문에
null
입니다. 이 반의 선생님 옵션은null
입니다.>>> t1 = Headmaster.objects.all().first()
>>> t1
>>> c1 = Class.objects.all().first()
<Headmaster: >
>>> c1
<Class: >
>>> c1.teacher
<Headmaster: >
>>> t1.delete()
(1, {
'modelsapp.Headmaster': 1})
>>> c1 = Class.objects.all().first()
>>> c1
<Class: >
>>> c1.teacher
>>> # , C1 None
삭제한 후에 데이터를 다시 한 번 얻는 것을 기억해야 한다. 그렇지 않으면 본 결과에서 선생님의 반 데이터를 얻었는지 아니면 이전에 얻었는지 기억해야 한다
다대다관계
모델에 ManyToManyField 필드를 사용하여 다중 관계식 정의
여러 쌍의 다중 관계는 관련이 있을 수도 있고 없을 수도 있기 때문에 명확하게 지정할 필요가 없다
on_delete
속성생활 속 에서 다대다 관계: 한 음악가 는 여러 밴드 에 예속될 수 있고, 한 밴드 는 여러 음악가 가 가 있을 수 있다
class Artist(models.Model):
artist_name = models.CharField(max_length=50)
def __str__(self):
return self.artist_name
class Band(models.Model):
band_name = models.CharField(max_length=50)
artist = models.ManyToManyField(Artist)
def __str__(self):
return self.band_name
음악가와 밴드를 만들다
>>> from bbs.models import Artist,Band
>>> A1 = Artist.objects.create(artist_name='Jack')
>>> A2 = Artist.objects.create(artist_name='Bob')
>>> B1 = Band.objects.create(band_name='FiveMonthDay')
>>> B2 = Band.objects.create(band_name='SHE')
두 밴드를 만들어서 뮤지션의 추가를 하도록 하겠습니다.
다중 필드를 추가할 때
add
함수를 사용하여 다중 값을 증가할 수 있습니다>>> B1.artist.add(A1,A2)
>>> B2.artist.add(A2)
B1
밴드 포함A1
, A2
두 멤버B2
밴드 멤버 포함 A1
>>> B1.artist.all()
[<Artist: Bob>, <Artist: Jack>]
>>> B2.artist.all()
[<Artist: Jack>]
음악가 표에서 어떤 악가가 어떤 밴드에 속하는지 찾을 수 있다
>>> Band.objects.filter(artist=A1) # 。
[<Band: SHE>, <Band: FiveMonthDay>] # A1 ,SHE FiveMonthDay
>>> Band.objects.filter(artist=A2)
[<Band: SHE>]
이 뮤지션이 어떤 밴드에 있는지 찾아보셔도 돼요.
>>> A1.band_set.all() #
[<Band: SHE>, <Band: FiveMonthDay>]
>>> A2.band_set.all()
[<Band: SHE>]
다중 연관 필드 삭제
remove
를 사용하여 관계 끊기직접 사용
delete
대신 remove
데이터 간의 연결은 끊어지지만 삭제되지는 않음지금 B1 밴드에서 A1 악가를 삭제합니다.
>>> B1.artist.remove(A1)
>>> B1.artist.all()
<QuerySet [<Artist: Bob>]>
연관 테이블에 대한 질의
조회하고자 하는 필드가 관련 테이블에 있으면
__
를 사용하여 테이블 간의 조회 작업을 진행합니다다대일 관계의 부자표를 만들면, 한 아버지에게는 여러 아들이 있을 수 있다.
class Father(models.Model):
name = models.CharField(max_length=30)
age = models.CharField(max_length=30)
def __str__(self):
return self.name
class Son(models.Model):
father = models.ForeignKey(Father,on_delete=models.CASCADE)
name = models.CharField(max_length=30)
def __str__(self):
return self.name
데이터 생성
>>> f1 = Father.objects.create(name='Jack',age='30')
>>> s1 = Son.objects.create(name='Json',father=f1)
>>> s2 = Son.objects.create(name='Json2',father=f1)
>>> f2 = Father.objects.create(name='Bob',age='40')
>>> s3 = Son.objects.create(name='Json3',father=f2)
모든 아버지 이름이
jack
인 아이 조회>>> Son.objects.filter(father__name__exact='Jack')
[<Son: Json>, <Son: Json2>]
모든 아들의 이름이
J
로 시작하는 아버지를 조회하다>>> Father.objects.filter(son__name__startswith='J')
[<Father: Jack>, <Father: Jack>, <Father: Bob>]
어떤 아버지의 모든 아이를 얻고 어떤 데이터를 통해
_set
역방향 조회>>> f1.son_set.all()
>>> [<Son: Json>, <Son: Json2>]
데이터의 역방향 조회
기본적으로 어떤 데이터를 얻은 후에 우리는 모델 클래스 이름
_set
을 붙여서 역방향 조회를 실현할 수 있다.현재 두 개의 표를 군대와 병사표로 설계하였으며, 병사는 다대일 관련 군대이다
class Aramy(models.Model):
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class Soldier(models.Model):
aramy = models.ForeignKey(Aramy,on_delete=models.CASCADE)
name = models.CharField(max_length=30)
def __str__(self):
return self.name
일부 데이터 생성
>>> a1 = Aramy(name=' ')
>>> a1.save()
>>> s1 = Soldier(name=' ',aramy=a1)
>>> s1.save()
>>> s2 = Soldier(name=' ',aramy=a1)
>>> s2.save()
soldier_set
를 통해 우리는 대응하는 병사표에 연결할 수 있다또한 반환 결과에 대응하여 우리가 자주 사용하는
filter
,exclude
등 조회 조작을 실행할 수 있다>>> a1.soldier_set.all()
[<Soldier: >, <Soldier: >]
>>> a1.soldier_set.filter(name=' ')
[<Soldier: >]
관련 필드의
related_name
값을 정의하여 사용자 정의 역방향 검색 이름을 실현할 수 있습니다또한
related_name
값은 고유해야 합니다.class Aramy(models.Model):
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class Soldier(models.Model):
aramy = models.ForeignKey(Aramy,on_delete=models.CASCADE,related_name='soldier')
name = models.CharField(max_length=30)
def __str__(self):
return self.name
다음에 어떤 데이터를 통해 역방향 조회를 한다
>>> a1 = Aramy.objects.all()[0]
>>> s1 = Soldier.objects.get(name=' ')
>>> a1.soldier.all()
[<Soldier: >, <Soldier: >]
참고: relatedname은 반드시 유일한 값입니다. 그렇지 않으면 반대로 찾을 때 이성 오류가 발생합니다.
related_name
를 +
로 초기화하여 역방향 조회를 취소할 수도 있습니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Django 라우팅 계층 URLconf 작용 및 원리 해석URL 구성(URLconf)은 Django가 지원하는 웹 사이트의 디렉토리와 같습니다.그것의 본질은 URL과 이 URL을 호출할 보기 함수 사이의 맵표입니다. 위의 예제에서는 URL의 값을 캡처하고 위치 매개 변수로...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.