코딩 개발일지

장고(Django) 역참조 / form.py 본문

AI 본 교육/AI 6주차

장고(Django) 역참조 / form.py

호기호 2023. 9. 12. 14:50

정참조와 역.참.조

 

장고에서 역참조와 form.py를 만들어서 쓰는 것은 생각보다 너무나 기본적이고, 중요하고, 아주 많이 쓰이는 것이였다.

근데 난 왜 이제 알았을까?! 크흠..


만약 models.py에 class 두개가 있고, 1:N 관계라고 하자.

예를 들어

class Human(models.Model):
    name = models.CharField()
class Dog(models.Model):
    owner = owner = models.ForeignKey(Human# Human 에서 외래키를 가져옴 (1:N)
    name = models.CharField()

이 때, Dog 가 Human을 참조 하는것이 정참조 이고,

반대로, Human이 Dog를 참조하는 것이 역참조 이다.


정참조는 Foreign Key 속성이 있는 객체(Dog)에서 없는 개체(Human)를 참조하는 것이고, get을 통해 가져온다.

dog = Dog.objects.get(pk=1)

dog.owner.name

 

역참조는 Foreign Key 속성이 없는 객체(Human)에서 관계된 모델(Dog)을 참조하는 경우이다.

person = Human.objects.get(name='이기호')

person.dog.name # XXX (가져올 방법이 없음)
 
person_dogs = person.dog_set.all()

'person' 은 맨 윗줄에서 정의를 해줬고, person table에는 dog의 column 값이 없지만, dog에서 가져오고 싶을 때 역참조를 쓰느 것이다!!!!

person.dog_set.all()

가져올 테이블 + 언더바 + set 을 잘 기억해 두자!!!!


역참조를 사용할 수 있는 두 번째 방법이 있다.

models.py 에서 ForeignKey 속성에 related_name을 추가해 준다.

class Dog(models.Model):
    owner = owner = models.ForeignKey(Human, related_name='dogs')
    name = models.CharField()

그러면

person = Human.objects.get(name='윤정호')

person_dogs = person.dogs.all()

이렇게 쓸 수 있다.


form.py 기능, 언제 쓰는걸까? 꼭 필요한가?

 

나는 이미 form태그를 많이 썼다. html에서 form태그를 통해 views.py에 있는 함수를 post해줄 수 있다는 것은 알고 있다.

근데 form.py는 뭘까??? 아직 배우지 않았지만, 구글링을 해보면 나빼고 전부 사용하고 있는 모습을 볼 수 있다...🤣

 

결론부터 말하자면 form.py의 역할은 데이터의 유효성 검사 (검증) 이다.

데이터가 유효(is_valid)하다고 검증이 되면, 이 데이터를 통과시켜서 action을 취한다.

유효하지 않다면(is_invalid) 에러메세지와 함께 form에 해당하는 페이지로 돌려보낸다.

위 그림은 화살표 방향을 보면서 읽어보면, form의 기능을 잘 알 수 있는 그림이다.


그렇다면, Django에서 forms.py에는 뭘 써야 하고, 정확히 무슨 역할인걸까???

 

forms.py폴더를 생성하고, django내에 있는 forms를 import해주고 사용할 수 있다.

그리고 class를 만들어서 views.py의 함수, html에 적용할 수 있다.

유효성 검사에 대한 긴 코드를 분리할 수 있는 아주 좋은 기능이고, 코드 간결해진다.

 

form에 있는 class를 정의할 때, 여러가지 field들을 작성하고, 이 field들을 유효성 체크하는 것이다.

예시)

from django import forms
 
class CompanyForm(forms.Form):
    name = forms.CharField(max_length=10, requried=True)
    date_establish = forms.DateField()
 
    class Meta:
        fields = ['name', 'date_establish']

name과 date_establish라는 두 변수를 필드로 선언하면, html에서 쓸 수 있다.