django url 매핑 규칙

kangjuju·2023년 4월 26일
0

Django

목록 보기
6/6

url 매핑 규칙 <int:>

query paramter : url의 ? 뒤의 파라미터
path parameter : url 사이에 있는 파라미터. 파라미터 타입을 정의한다. 이 규칙의 예는 아래와 같다.
int : 정수형 숫자
str : 모든 문자열
slug : -(하이픈)이나 _(언더스코어)를 포함한 영숫자, 문자열

먼저 html에서 두가지 방법의 요청을 확인해보자.

<!--  하드코딩-->
<li><a href="/gogo/{{q.id}}/">{{q.question_text}}</a></li>
 <!-- 소프트코딩 -->
<li><a href="{% url 'detail' q.id%}">{{q.question_text}}</a></li>

소프트 코딩 부분에서의 detail은 urls의 name(별명).
예를 들면 /gogo/2/ 와 같은 요청을 보내고, 이를 urls에서 받을땐 아래처럼 사용한다.

urlpatterns = [
    path('<int:question_id>/',views.DetailFunc,name='detail'), #/gogo/1또는2/ 
    ]

다음 views에서 넘어온 데이터를 사용할땐

def DetailFunc(request,question_id): #<int:question_id>
    '''
    try:
        question = Question.objects.get(pk=question_id)
    except Question.DoesNotExist:
        raise Http404('Questrion does not exist!')
    '''
    question = get_object_or_404(Question,pk=question_id) #위의 try를 shortcut으로 함축
    
    for cho in question.choice_set.all(): #오브젝트지정 후 전부 가져옴
        print(cho.choice_text)
	return render(request, 'detail.html',{'question':question})

이 반환값을 html에서 받을때.

<body>
<H2>{{question}}</H2>
<!-- http://localhost/gogo/1/vote/?choice=1 -->
<form action="{% url 'vote' question.id %}" method="post">{% csrf_token %}
	{% for cho in question.choice_set.all %}
		<!-- 인덱싱 -->
		<input type="radio" name="choice" id="choice{{forloop.counter}}" value="{{cho.id}}">
		<label for="choice{{forloop.counter}}">{{cho.choice_text}}</label> 
	{% endfor %}
	<br>
	<input type="submit" value="투표확인">
</form>
</body>
  • question.choice_set.all 은 파이썬 코드 question.choice_set.all()로 변환됨. 이는 iterable 객체를 반환하게 됨

여기서 /gogo/2/vote?choice=1 을 위한 url매핑을 한번 더했다. 주석의 형태를 띄는 url를 만드는 것이 목적. urls에 vote별명을 받기 위한 코드를 추가했다.

path('<int:question_id>/vote',views.VoteFunc,name='vote'), #/gogo/1또는2/vote

이에 해당하는(vote요청) views 함수

def VoteFunc(request,question_id):
    question = get_object_or_404(Question,pk=question_id)
    try:
        sel_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError,Choice.DoesNotExist):
        return render
        (request, 'detail.html',{'question':question,'error_msg':'1개의 항목을 꼭 선택하세요'})
    
    sel_choice.votes += 1 #sel_choice : Choice 테이블
    sel_choice.save() #투표수 갱신 
    
    # reverse() : 매핑되었던 url 패턴으로부터 url String 얻기 (/gogo/1/results/)
    return HttpResponseRedirect(reverse('results',args=(question_id,)))
  • POST요청을 get하여 파라미터를 받고, question_id는 항상 따라다니며 알맞는 링크를 만든다.
    get_object_or_404 short cut으로 질문 id에 맞는 객체를 받고, POST로 받은 파라미터를 이용해 선택항목에 대한 객체를 받았다.

  • reverse() 함수의 용도를 잘 기억하자.

결과 확인을 위한 result.html / views. 리다이렉트로 return
path('<int:question_id>/results/',views.ResultFunc,name='results'), #/gogo/1또는2/results

def ResultFunc(request,question_id):
    question = get_object_or_404(Question,pk=question_id)
    return render(request,'result.html',{'question':question})

HTML

<h2>{{question.question_text}}</h2>
결과 : <br/>
{% for cho in question.choice_set.all %}
	<li>
		{{cho.choice_text}} - {{cho.votes}} 표
	</li>
{% endfor %}
<a href="{% url 'detail' question.id %}">같은 항목 다시 투표</a>

0개의 댓글