장고:클래스형 뷰, 제네릭 뷰
편집하기
Sam
(
토론
|
기여
)
님의 2021년 1월 6일 (수) 19:38 판
(
→Mixin
)
(
차이
)
← 이전 판
|
최신판
(
차이
) |
다음 판 →
(
차이
)
둘러보기로 이동
검색으로 이동
경고: 이 문서의 오래된 판을 편집하고 있습니다.
이것을 게시하면, 이 판 이후로 바뀐 모든 편집이 사라집니다.
경고:
로그인하지 않았습니다. 편집을 하면 IP 주소가 공개되게 됩니다.
로그인
하거나
계정을 생성하면
편집자가 사용자 이름으로 기록되고, 다른 장점도 있습니다.
스팸 방지 검사입니다. 이것을 입력하지
마세요
!
{{장고}} 작정하고 장고의 코드를 참고해 살펴보는 게 좋겠다. <br /> =클래스형 뷰= 기본적으로 뷰는 함수로 만들지만, 코드가 길어지면 클래스형 뷰가 필요하다. 중급자 이상으로 넘어가기 위해선 필수적으로 숙달해야 할 내용. 함수형 뷰보다 재사용하기가 쉬워 고급사용자가 될수록 더 많이 사용하게 되는 형태. =제네릭 뷰= View는 기본적으로 함수로 만들지만, 이미 자주 쓰이는 기능을 또 새로이 만들어야 할까? 이미 개발된 뷰가 있다.이를 제네릭뷰라 부르며, 클래스형으로 구성되어 있다. 장고에서 제공하는 뷰이다. 크게 4가지 분류의 클래스뷰가 있다. CRUD 기능을 제공하게끔. 장고의 특성이다. CRUD 구현이 쉬워.[일반 뷰에서도 이런 틀로 정리해보자.] {| class="wikitable" |+ !기능 !뷰 이름 !비고 ! |- |Create |CreateView |form_class = 사용할 폼이름 | |- |Read |DetailView | | |- |Update |UpdateView |기본적으로 CreateView와 같은 속성을 갖는다. | |- |Delete |DeleteView | | |} Class형 view가 편하다곤 하지만.. 그 강점은 장고가 업데이트 되 때에 일관성 있게 작동할 가능성을 높여준다는 것 외엔.. 딱히 모르겠다. 사실, 엄청 편리한 것도 모르겠고.. 공부를 위해선, 전체작동방식의 느낌을 알기 위해선 함수를 처음부터 짜는 view가 더 좋은 듯하다.(장고 자체를 더 공부해야 한다는 점에서 별로다; 그럴바엔 파이썬 자체를 더 다뤄보지!) 내부적으로 어떻게 작동하는지 알기 어려워, 도리어 혼란스러울 때도 있다. <nowiki>#</nowiki>제네릭 뷰에서 데이터를 탬플릿에 전달할 때 리스트 이름이 지정되어 있는데, 리스트 이름을 바꾸려면 get_queryset함수 안에 이 변수를 넣는다.(글쓰기 기능구현 참조) context_object_name='바꿀리스트명' 기본적으로 짧기 때문에 urls.py 안에 바로 기입해줘도 가독성에 무리가 적다. ==제네릭 뷰의 변수== {| class="wikitable" |+ !변수 !설명 !사용예 |- |fields |어떤 필드를 기입할지. |fields=['subject', 'text'] |- |tempalte_name |기본 탬플릿 말고 따로 지정할 때 |template_name='app/list.html' |- |success_url |함수의 기능이 성공했을 때 어떤 url로 보낼지 지정 |success_url='/app/' |- |model |어떤 모델에 대한 뷰인지. |model = User |- |context_object |불러온 모델명을 탬플릿에 보낼 때 그대로 보내는데, 다른 이름을 사용하고 싶을 때 |context_object = target_user |- | | | |} self.get_object() : 사용하고 있는 모델의 객체를 가져온다. ===함수=== {| class="wikitable" !함수 !설명 !사용예 |- |get_success_url |성공 후 진행할 작업을 여기에 담는다. |<syntaxhighlight lang="python"> def get_success_url(self): # 기존 함수를 덧쓴다. 작성 후에 해당 글을 보여주게끔. return reverse('pool:detail', kwargs={'pk': self.object.question.pk}) </syntaxhighlight> |- |form_valid |폼이 적절할 때 실행할 함수. |<syntaxhighlight lang="python"> def form_valid(self, form): # 폼에 이상이 없으면 실행. temp = form.save(commit=False) # 임시 저장. 폼 외의 다른 내용을 조작하고 싶을 때 사용한다. 조작 temp.save() # 최종 저장 return super().form_valid(form) </syntaxhighlight> |} ==ListView== 많은 객체들을 한번에 보여주기 위한 뷰. 기본 형태는 다음과 같다.<syntaxhighlight lang="python"> class 뷰이름(ListView): model = 사용할 모델 context_object_name = '모델을 표현할 이름' template_name = '탬플릿 경로' paginate_by = 몇 개 단위로 보여줄 것인가. </syntaxhighlight>이렇게 만들면 객체리스트가 <code>모델명_list</code> 형태로 탬플릿에 전달된다. ===pagination=== 객체가 너무 많을 때 한 화면에 모든 것을 보여줄 순 없다. 이런 문제를 해결하기 위해 한 화면에 보여줄 객체의 갯수를 정해 페이지화 해야 한다. 혹은... infinite scroll 형식으로 만들 수도 있지만 이를 위해선 자바스크립트 사용이 필요하다. 페이지 버튼은 탬플릿에 따로 기입한다. 다음과 같은 형태로 page 변수를 get 방식으로 넘겨준다.<syntaxhighlight lang="html+django"> <a href="{% url '앱:인덱스' %}?page={{ page_obj.number}}">{{ page_obj.number }}</a> </syntaxhighlight>페이지 버튼만 따로 떼어 html을 만든 후 include를 하기도 한다. ==유의사항== ===url.py 에서 사용할 때=== 제네릭 뷰를 사용할 때 urls.py에서 어떤 변수명을 사용하는 게 아니라, 변수명들이 예약되어 있다. {| class="wikitable" |+예약된 변수명 !변수 !설명 |- |<int:pk> |기본키를 받아들이는 변수 |- | | |- | | |} ====함수명 뒤에 .as_view()를 붙인다.==== 그냥 view를 사용할 땐 함수명을 쓰면 됬지만, 제네릭 뷰에선 마지막에 .as_view()를 붙여주어야 한다. ===탬플릿에서 사용할 때=== ListView에선 모델명_list 라는 변수로 탬플릿에 전달된다. DetailView에선 object라는 변수로 모델이 탬플릿에 전달된다. <br /> =Mixin[따로 목차를 분류해야겠네;]= 클래스 뷰를 사용할 때 특정한 기능이 다른 뷰로 분리되어 있을 때. 예컨대, DetailView에선 form이 없기 때문에 댓글을 쓸 수가 없다. 이땐 다중상속을 받아 기능을 구현할 수 있다.<syntaxhighlight lang="python"> class 뷰이름(DetailView, FormMixin): form_class = 폼이름 ... def form_valid(self, form): ... writer = self.request.user return super().form_valid(form) </syntaxhighlight>위와 같이 Mixin으로 없는 기능을 가져다 넣어 사용할 수 있다. <br /> === MultipleObjectMixin === 여러 오브젝트를 다루기 위한 믹스인.<syntaxhighlight lang="python"> class 뷰이름(DetailView, MultipleObjectMixin): form_class = 폼이름 ... paginate_by = 10 def get_context_data(self, **kwargs): object_list = 모델.objects.filter(필터링조건) return super(뷰이름,self).get_context_data(object_list=object_list, **kwargs) </syntaxhighlight>본문과 리스트를 동시에 띄우기 위한 작업이다. <br /> == RedirectView == <syntaxhighlight lang="python"> class 뷰이름(RedirectView): def get_redirect_url(self, *args, **kwargs): return 보낼 주소 def get(self, request, *args, **kwargs): object = get_object_or_404(모델, pk=키값) </syntaxhighlight> = 구독 기능 = 찬찬히 보면서 옮기자.. 문제를 풀었는가 여부도 이걸로 구현 가능할듯. 유저와 프로젝트를 포린키로 가져온다. 모델작성<syntaxhighlight lang="python"> class 모델명(models.Model): class Meta: unique_together = ('속성1', '속성2') </syntaxhighlight>이 둘의 조합은 오직 하나만 존재하도록 설정한다. 이 모델을 filter로 불러와 유저와 객체가 일치하는 것을 찾아 구독관계를 찾곤 한다. filter(user=user, project=객체명) 형태로 일치하는지 여부만 찾으면 된다. === Fieldlookup === filter 안에서 언더바 2개로 작동하는 장고의 기능. 값__in 은 SELECT ... WHERE 값 IN ...; 과 대응한다. 조금 더 복잡한 DB query를 사용하기 위한 기능이다. 장고 도큐먼트를 보면.... 나온다. === 필터 이후 처리 === 필터링으로 구독관계 객체를 불러왔다곤 하지만, 이것이 구독한 객체를 보여주지 않는다. 이를 위해 .values_list('모델명')이 쓰인다. 객체 = ...filter(조건).values_list('모델명') 형태로 쓰면 필터에 걸린 것들 중 해당 모델에 해당하는 것을 가져온다.(제한적으로 쓰일 것 같지만, 강력하고 어려운 개념이네;) 그럼 이를 불러오려는 모델처럼 다룰 수 있다. === 아이디어 === 게시글목록 중 글 자체에 대한 것과, 검색부분과... 다 따로만드는 게 좋을 듯하다. 글 자체에 대한 건 즐겨찾기 한 문제들을 불러올 수 있잖아. 옵션에 따라 글부분만 달리 나타낼 수도 있고. <br />
요약:
학교의 모든 지식. SMwiki에서의 모든 기여는 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 라이선스로 배포된다는 점을 유의해 주세요(자세한 내용에 대해서는
학교의 모든 지식. SMwiki:저작권
문서를 읽어주세요). 만약 여기에 동의하지 않는다면 문서를 저장하지 말아 주세요.
또한, 직접 작성했거나 퍼블릭 도메인과 같은 자유 문서에서 가져왔다는 것을 보증해야 합니다.
저작권이 있는 내용을 허가 없이 저장하지 마세요!
취소
편집 도움말
(새 창에서 열림)
이 문서에서 사용한 틀:
틀:장고
(
원본 보기
) (보호됨)
둘러보기 메뉴
개인 도구
로그인하지 않음
토론
기여
로그인
이름공간
문서
토론
한국어
보기
읽기
편집
원본 편집
역사 보기
더 보기
검색
둘러보기
대문
최근 바뀜
임의의 문서로
미디어위키 도움말
도구
여기를 가리키는 문서
가리키는 글의 최근 바뀜
특수 문서 목록
문서 정보