장고:글쓰기
편집하기
Sam
(
토론
|
기여
)
님의 2020년 11월 1일 (일) 14:43 판
(
→글 작성
)
(
차이
)
← 이전 판
|
최신판
(
차이
) |
다음 판 →
(
차이
)
둘러보기로 이동
검색으로 이동
경고: 이 문서의 오래된 판을 편집하고 있습니다.
이것을 게시하면, 이 판 이후로 바뀐 모든 편집이 사라집니다.
경고:
로그인하지 않았습니다. 편집을 하면 IP 주소가 공개되게 됩니다.
로그인
하거나
계정을 생성하면
편집자가 사용자 이름으로 기록되고, 다른 장점도 있습니다.
스팸 방지 검사입니다. 이것을 입력하지
마세요
!
{{장고}} =개요= 글쓰기 기능을 구현하기 위해 정리한 문서. 기본적으로 포스팅 기능이지만, 모델명을 Post로 하기엔 전송방식인 post와 혼동이 오곤 해서 question으로 구현한다. =url 작성= urls.py 안에 필요한 기능을 다 담아주어야 한다. 예컨대, 글을 쓴다면 만들기, 편집, 삭제기능을 만들어주어야 하기에 다음과 같이 기입한다. (뷰의 설정이나, import방식에 따라 뷰를 불러오는 방식이 달라질 수 있다.) {| class="wikitable" |+ !일반적으로 코드를 짜는 경우 !제네릭 뷰를 사용하는 경우 |- |<syntaxhighlight lang="python"> from django.urls import path from . views #해당 앱의 뷰를 불러온다. app_name = 'pool' urlpatterns = [ path('question/', views.list, name='list'),#글의 리스트롤 보여주는 화면. path('question/detail/<int:question_id>/', views.detail, name='detail'),#글의 내용을 보여주는 화면. path('question/create/<int:question_id>/', views.create, name='create'),#글의 작성화면 path('question/modify/<int:question_id>/', views.modify, name='modify'),#글의 수정화면 path('question/delete/<int:question_id>/', views.delete, name='delete'),#글의 삭제화면 ] </syntaxhighlight> |함수명을 바꾸어주어야 한다. views.클래스뷰명.as_view()), 형태로. 클래스형 뷰임을 지정해주기 위해. |} <nowiki>#</nowiki>아직 함수를 짜주진 않았지만, 앞으로 만들 함수에 대해 연결해두자. =모델 작성= 글에서 포함해야 할 것들이 있다. 작성자, 작성일자, 내용 등의 요소를 포함하여 모델을 작성한다. /앱/models.py 안에 작성한다.<syntaxhighlight lang="python"> from django.contrib.auth.models import User from django.db import models class Question(models.Model):#세부내용은 필요에 따라.. author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='author_question') subject = models.CharField(max_length=200) content = models.TextField() create_date = models.DateTimeField() modify_date = models.DateTimeField(null=True, blank=True) def __str__(self):#관리자페이지에 나타낼 객체 이름. return self.subject#이 객체의 subject를 이름으로 쓰겠다는 의미. </syntaxhighlight> ===관리자 기능에서 확인=== 모델이 제대로 작성되고, 글이 제대로 생성될 수 있는지 관리자기능에 등록한 후 작성해보자. 관리자 등록은 [[장고:관리자페이지]] 참조. 이상이 없으면 뷰 작성으로 넘어가자. =뷰, 탬플릿 작성= 탬플릿과 연관이 깊으니, 같이 짜주자. 한 단계, 한 단계 차근차근 작동을 확인하며 넘어가자. ==리스트 보기== {| class="wikitable" ! !일반적으로 코드를 짤 경우 !제네릭뷰(클래스형 뷰)를 쓰는 경우 |- |view 작성 |전체 글을 본다.<syntaxhighlight lang="python"> from django.shortcuts import render from .models import * #모델을 불러온다. def list(request): question_list=Question.objects.order_by('-create_date') #만들어진 순서의 역순으로 정렬 context={'question_list':question_list, } #템플릿으로 보내줄 내용을 담는다. return render(request, 'list.html', context) #list.html로 보낸다. </syntaxhighlight> |전체 글을 본다.<syntaxhighlight lang="python"> from django.views import generic from .models import Question class ListView(generic.ListView): def get_queryset(self): return Question.objects.order_by('-create_date') #템플릿 명이 명시적으로 지정되지 않은 경우에는 자동으로 모델명_list.html을 템플릿명으로 사용. </syntaxhighlight> |- |template작성 |경로에 맞게 해주면 되는데, 위 뷰의 경우엔 /앱이름/template/list.html 에 만들어준다. 만들어진 html파일의 body에 다음과 같이 넣어준다. 상황에 맞게 표를 만들든, 목차를 만들든 html을 짜면 될 터.<syntaxhighlight lang="html"> {% if question_list %} <ul> {% for question in question_list %} <li><a href="{% url 'pool:detail' question.id %}">{{question.subject}}</a></li> {% endfor %} </ul> {% else %} {% endif %} </syntaxhighlight> |템플릿 명이 명시적으로 지정되지 않은 경우에는 자동으로 모델명_list.html을 템플릿명으로 사용. /앱이름/template/question_list.html 을 좌측과 같이 짜주면 된다.<syntaxhighlight lang="python"> #따로 탬플릿 명을 명시하려면 다음의 변수를 get_queryset함수 안에 넣는다. template='앱이름/list.html' </syntaxhighlight>탬플릿에 전달되는 리스트는 question_list라는 이름이었는데, 전달할 이름을 바꾸려면 다음과 같이 넣어준다.<syntaxhighlight lang="python"> #탬플릿에 전달될 리스트 이름을 바꾸려면 get_queryset함수 안에 이 변수를 넣는다. context_object_name='바꿀리스트명' </syntaxhighlight> |} {| class="wikitable" |- |전체 글을 본다.<syntaxhighlight lang="python"> from django.shortcuts import render from .models import * #모델을 불러온다. def list(request): question_list=Question.objects.order_by('-create_date') #만들어진 순서의 역순으로 정렬 context={'question_list':question_list, } #템플릿으로 보내줄 내용을 담는다. return render(request, 'list.html', context) #list.html로 보낸다. </syntaxhighlight> |} ==글 보기== 리스트에서 글을 클릭하면 글의 상세내용을 볼 수 있어야 한다. {| class="wikitable" ! !일반적으로 코드를 짤 경우 !제네릭뷰(클래스형 뷰)를 쓰는 경우 |- |view 작성 |글 하나의 내용을 본다. get_object_or_404를 쓴다. id에 해당하는 객체가 없으면 서버에서 에러를 일으키는데, 이는 서버에러로 잡힌다. 에러의 방향성을 명확히 지정해주기 위해. 404에러를 부르게끔!<syntaxhighlight lang="python"> from django.shortcuts import render, get_object_or_404 from .models import * #모델을 불러온다. def detail(request,question_id):#url에서 매핑된 question_id가 전달된다. question=get_object_or_404(Question, pk=question_id) context={'question':question} return render(request, 'detail.html', context) </syntaxhighlight> |<syntaxhighlight lang="python"> class DetailView(generic.DetailView): model = Question #템플릿 명이 명시적으로 지정되지 않은 경우에는 자동으로 모델명_detail.html을 템플릿명으로 사용 </syntaxhighlight> |- |template작성 |경로에 맞게 해주면 되는데, 위 뷰의 경우엔 /앱이름/template/detail.html 에 만들어준다. 만들어진 html파일의 body에 다음과 같이 넣어준다. 상황에 맞게 표를 만들든, 목차를 만들든 html을 짜면 될 터. <nowiki>{{변수.속성}}</nowiki> 형태로 필요한 데이터를 가져온다.<syntaxhighlight lang="html"> <h1>{{ question.subject }}</h1> <div> {{ question.content }} </div> </syntaxhighlight> | |} ==글 작성== {| class="wikitable" ! !일반적으로 코드를 짤 경우 !제네릭뷰(클래스형 뷰)를 쓰는 경우 |- |template작성 | colspan="2" |위에서 만든 list.html을 수정한다. 글 작성을 위한 링크 추가.<syntaxhighlight lang="html"> <a href="{% url '앱이름:question_create' %}" class="btn btn-primary">등록</a> </syntaxhighlight> |- |form 작성 |장고에선 form이라는 형태로 입력을 받을 수 있게 고안해두었다. 앱 디렉터리 안에 form.py 파일을 새로 작성한다. 모델과 연결된 모델폼을 사용한다.<syntaxhighlight lang="python"> from django import forms from .models import Question class QuestionForm(forms.ModelForm):#모델폼 상속 class Meta: model = Question#연결할 모델 지정 fields = ['subject', 'content']#모델의 어떤 부분을 입력할지 지정 </syntaxhighlight><br /> |<br /> |- |view 작성 |글을 작성하기 위한 공간 만들기. 일반적으로 페이지를 불러오는 것과 데이터를 저장하는 데 같은 링크를 사용한다. 페이지 요청방식에 따라 달리 작동하게 하면 되는데, POST요청이면 데이터를 저장. (링크를 타고 오는 경우, GET 요청으로 들어온다.) 폼을 사용하는 경우.<syntaxhighlight lang="python"> from .forms import QuestionForm#위에서 작성한 폼 불러오기 def create(request): if request.method == 'POST':#포스트로 요청이 들어온다면... 글을 저장. form = QuestionForm(request.POST) #폼을 불러와 내용입력을 받는다. if form.is_valid():#내용이 모델에 맞지 않는 경우, 에러 반환. question = form.save(commit=False) #commit=False 옵션은 저장하지 않고 불러오기만 한다는 의미. #question모델에서 create_date옵션이 null=False이기 때문에 그냥 저장하면 에러가 난다. question.author = request.user # 추가한 속성 author 적용 question.create_date = timezone.now()#현재시간으로 자동 적용 question.save() return redirect('pool:index') #작성이 끝나면 목록화면으로 보낸다. else:#포스트 요청이 아니라면 내용작성 화면으로. form = QuestionForm() context = {'form': form} return render(request, 'create.html', context) </syntaxhighlight> |<syntaxhighlight lang="python"> from django.views import generic from django.urls import reverse_lazy class create(edit.CreateView): model = Question feilds = ['필드명', '필드명',...] success_url=reverse_lazy('앱이름:detail')#작성에 성공한 경우 보낼 탬플릿. template_name_suffix='_create' #사용하는 탬플릿 명을 '모델명_create.html'로 바꾼다는 의미. 접미사만 바꾼다. #기본 탬플릿은 '모델명_form.html'로 나타난다. </syntaxhighlight> |- |template작성 | colspan="2" |view에서 보내는 탬플릿을 작성한다. 폼을 사용하는 경우.<syntaxhighlight lang="html"> {% extends '연장할탬플릿.html' %} {% block content %} <form method="post"> {% csrf_token %} {{ form.as_p }} <input type="submit" value='나타낼 텍스트'> </form> {% endblock %} </syntaxhighlight><nowiki>{{form.as_p}}</nowiki>는 폼으로부터 전달된 객체. 입력을 위한 코드를 자동으로 작성한다. 자동으로 <nowiki><p>태그로 감싸준다. 자동으로 생성되기 때문에 CSS를 적용할 수 없는데...</nowiki> forms.py를 수정하면 가능하다. |} ==뷰 작성== 뷰가 많아지면 /앱/views/posting_view.py 따위의 이름으로 작성한다. {| class="wikitable" |+ ! ! |- | | |- |글작성 |<syntaxhighlight lang="python"> from django.contrib.auth.decorators import login_required #로그인 기능 from django.shortcuts import render, get_object_or_404, redirect from django.utils import timezone from ..forms import QuestionForm #폼을 불러온다. from ..models import Question #모델을 불러온다. @login_required(login_url='common:login')#로그인이 필요없으면 빼도 됨. def create(request): if request.method == 'POST':#포스트로 요청이 들어온다면... 글을 올리는 기능. form = QuestionForm(request.POST) #폼을 불러와 내용입력을 받는다. if form.is_valid(): question = form.save(commit=False) question.author = request.user # 추가한 속성 author 적용 question.create_date = timezone.now() question.save() return redirect('pybo:index') #작성이 끝나면 목록화면으로 보낸다. else:#포스트 요청이 아니라면.. form으로 넘겨 내용을 작성하게 한다. form = QuestionForm() context = {'form': form} return render(request, 'pybo/question_form.html', context) </syntaxhighlight> |- |글수정 | |- | |from django.contrib import messages |} <br />
요약:
학교의 모든 지식. SMwiki에서의 모든 기여는 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 라이선스로 배포된다는 점을 유의해 주세요(자세한 내용에 대해서는
학교의 모든 지식. SMwiki:저작권
문서를 읽어주세요). 만약 여기에 동의하지 않는다면 문서를 저장하지 말아 주세요.
또한, 직접 작성했거나 퍼블릭 도메인과 같은 자유 문서에서 가져왔다는 것을 보증해야 합니다.
저작권이 있는 내용을 허가 없이 저장하지 마세요!
취소
편집 도움말
(새 창에서 열림)
이 문서에서 사용한 틀:
틀:장고
(
원본 보기
) (보호됨)
둘러보기 메뉴
개인 도구
로그인하지 않음
토론
기여
로그인
이름공간
문서
토론
한국어
보기
읽기
편집
원본 편집
역사 보기
더 보기
검색
둘러보기
대문
최근 바뀜
임의의 문서로
미디어위키 도움말
도구
여기를 가리키는 문서
가리키는 글의 최근 바뀜
특수 문서 목록
문서 정보