본문 바로가기
  • 실행력이 모든걸 결정한다
Django

[Django] Admin 기초 / 동적 URL / views 기초

by 김코더 김주역 2021. 8. 9.
반응형

1. Admin 기초

Django에서는 기본적으로 관리자 페이지를 제공해 주는데, 주로 데이터베이스를 관리하는데 쓰인다.

/mysite/urls.py의 urlpatterns에서는, 프로젝트 생성 시부터 'admin/'이 등록되어 있다.

 

localhost:8000/admin으로 접속해보니 관리자 사이트가 나왔다.

 

관리자 페이지에 로그인하려면 계정을 생성해야 하며, 다음 명령어로 생성할 수 있다.

python manage.py createsuperuser

 

간단하게 Username, Email, Password만 설정하면 관리자 계정 생성이 완료된다.

 

다시 서버를 켜고 로그인을 시도해보자.

 

최초로 로그인에 성공하면 Groups, Users 2개의 테이블이 존재한다. Groups, Users 테이블이 보이는 이유는 settings.py에 django.contrib.auth 애플리케이션이 등록되어 있기 때문이다. auth 앱에 두 테이블이 미리 정의 되어 있는 것이다.

 

Users는 필자가 만든 "users" 앱에 대한 테이블이 아니고, 관리자 계정 테이블이라고 보면 된다.

 

그렇다면 관리자가 만든 앱에 대한 테이블은 어떻게 생성할까?

 

admin에서 관리할 테이블들은 /users/admin.py 파일에 등록하면 된다.

 

</users/admin.py>

from django.contrib import admin

from .models import Question, Choice

admin.site.register(Question)
admin.site.register(Choice)

 

(참고 - </users/models.py>)

from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

 

다시 서버를 키고 로그인해보니, Users앱의 두 테이블이 성공적으로 추가된 것을 확인할 수 있었다.

 

레코드의 조회, 추가, 변경, 삭제를 모두 admin 페이지 내에서 UI를 통해 수행할 수 있기 때문에, 편리한 관리를 기대해볼 수 있을 것이다.

 

 

 

2. 동적 URL (튜토리얼 문서 참고)

다음과 같이 <type:name> 형식으로 URL에 변수를 섞을 수도 있다. 꺾쇠 부분을 Path Converter라고 한다.

※ type으로 다음과 같은 것들이 올 수 있으며, 개발자가 추가로 타입을 등록할 수도 있다.

● str : /를 제외한 문자열

● path : /를 포함한 문자열

● int : 0 또는 양의 정수

● slug : slug 형식의 문자열 (ASCII, 숫자, 하이픈, 밑줄로만 구성)

● uuid : UUID 형식의 문자열

※ path 함수 대신 re_path 함수를 이용하여 URL 패턴에 정규표현식을 사용할 수도 있다. 예를 들어, path 함수에서의 <int:question_id> 부분이 re_path 함수에서는 (?P<question_id>정규식)으로 표현될 것이다.

 

그리고 해당 변수는 요청 처리 메소드의 파라미터로 받아서 사용하면 된다.

 

 

 

3. views 기초

1) Template 엔진

(1) Jinja2

Django는 Flask와 동일하게 기본 Template 엔진으로 Jinja2을 지원하며, Jinja2 엔진은 HTML 코드에 Python 코드를 섞어 쓸 수 있도록 한다. 이로 인해, HTML 코드에 Python 문법의 조건문, 반복문, 변수 등을 추가할 수 있기 때문에 동적인 페이지를 만들기 좋다.

그리고, HTML 파일은 반드시 "templates" 디렉토리 내에 저장해야 한다.

 

(2) HTML 파일 저장 디렉토리

Django 문서에서는 html 파일을 저장하는 디렉토리로 "[앱 명]/templates/"보다는, "[앱 명]/templates/[앱 명]/"을 사용하는 것을 권장한다. Django는 한 프로젝트에 여러 애플리케이션을 포함할 수 있기 때문에, 이로 인한 템플릿 이름의 중복 가능성을 염두한 것 같다.

 

<index.html>

HTML코드에 Python코드를 섞어 변수, 조건문, 반복문을 적용한 예제이다.

외부에서 n, rangeA값을 받아올 일만 남았다.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    n = {{n}} <br>

    {% if n >= 60 %}
        <h1>PASS</h1>
    {% else %}
        <h1>FAIL</h1>
    {% endif %}

    {% for i in rangeA %}
        <h2>{{i}}</h2>
    {% endfor %}
</body>
</html>

 

(3) 요청 처리 메소드

</users/views.py>

template에는 loader로 불러온 template을 저장하도록 하고, context에는 template에서 사용할 데이터들을 딕셔너리 형태로 담는다. 그리고, template에 context와 request를 담아 HttpResponse 객체로 반환했다.

from django.shortcuts import render
from django.template import loader
from django.http import HttpResponse

def index(request):
    n = 85
    a = 5
    template = loader.get_template('users/index.html')
    context = {
        'n':n,
        'rangeA':range(a), # 리스트를 넘기면 템플릿에서 for문에 이용할 수 있다.
    }
    return HttpResponse(template.render(context, request))
    # 아래 코드도 사용 가능!
    # return render(request, 'users/index.html', context)

 

 

(4) 실행 결과

값들이 모두 알맞게 출력되었다.

※ 템플릿 내에서 for 루프의 실행 횟수를 0부터 카운트하는 forloop.counter0 변수도 쓸 수 있으니 알아두자.

{% for i in arr %}
    <h2>{{forloop.counter0}}</h2>
{% endfor %}

 

(5) Jinja2 + model 객체 (튜토리얼 문서 참고)

모델이나 모델 리스트도 템플릿에서 참고할 수 있다. 모델의 속성은 .을 붙여 뒤에 작성하면 된다.

※ ~_set.all()은 1:N 관계에서 1 테이블에 연결된 N 테이블의 항목들을 반복 가능한 객체로 가져온다.

 

 

2) 404 에러 일으키기 (튜토리얼 문서 참고)

예외 처리를 위해 404에러를 직접 일으켜야 할 경우도 있다.

아래 예시에서는 검색 조건에 맞는 객체가 없을 때 발생하는 DoesNotExist 예외가 발생하면 에러를 일으킨다.

 

그리고 get_object_or_404() 메소드에게 예외 발생 결정권을 맡기는 방법도 있다. 객체를 못찾으면 에러를 발생시킨다.

※ 대상 객체를 리스트로 가져오는 get_list_or_404() 함수도 있다. 이 함수는 리스트가 비어 있으면 에러를 발생시킨다.

 

 

3) URL name (튜토리얼 문서 참고)

urlpatterns에서 경로별로 설정한 URL name을 template 내에서 사용할 수 있다.

서로 다른 앱 간에 이름이 중복됐을 경우에 이를 구분할 수 있게, app_name(namespace)을 앱의 이름으로 작성해두는 것이 좋다.

 

예) path('<int:question_id>/', views.detail, name='detail')에 대한 링크 설정

 

(Before) URL 이름을 사용하지 않았을 경우

href="/polls/{{ question.id }}/"

 

(After) URL 이름을 사용했을 경우

href="{% url 'polls:detail' question.id %}"

 

 

4) Redirect

HttpResponseRedirect 클래스를 사용하여 Redirect를 할 수 있다.

reverse() 함수는 URL 패턴명으로부터 URL 패턴을 구하는 함수로, args에는 URL에 포함된 변수값들을 ,(콤마)를 경계로 나열하면 된다.

반응형

댓글