Django 북마크 앱을 화면에 띄우려면 모델만 만드는 것으로는 부족하며, 앱 등록과 migration 뒤에 URL, view, template을 한 경로로 연결해야 합니다. Admin에 Post가 보인다는 사실은 모델과 데이터베이스가 연결됐다는 뜻이지 사용자 화면까지 연결됐다는 뜻은 아닙니다. 404, template 오류, 빈 목록, CSS 누락을 서로 다른 단계의 증상으로 나누면 고칠 파일을 빠르게 찾을 수 있습니다.
Django 북마크 앱이 Admin에는 보이는데 화면에 안 뜰 때: 파일 연결 순서
Django 파일은 요청 하나를 어떻게 나누나
원문은 Django 구조를 Model, View, Controller 역할로 나눠 설명합니다. 실제 파일 이름과 대응시키면 다음 흐름입니다.
models.py: 데이터베이스 테이블 구조를 class로 정의합니다.admin.py: model을 관리자 화면에 노출합니다.urls.py: 들어온 URL을 처리할 view로 보냅니다.views.py: 요청을 처리하고 데이터를 template에 전달합니다.templates: 사용자에게 보여줄 HTML을 둡니다.settings.py: database, 앱, template, static, media, 언어와 시간을 설정합니다.
한 파일이 다른 파일의 역할을 대신하지 않습니다. Admin에서 데이터가 보인다는 것은 model과 admin 연결이 됐다는 뜻일 뿐, 일반 사용자 URL과 template까지 연결됐다는 뜻은 아닙니다.
settings와 database를 먼저 고정하기
프로젝트는 다음 명령으로 만들고 설정 파일을 엽니다.
1
2
3
django-admin.py startproject website
cd website
vi settings.py
원문은 MySQL database에 DB0227, 사용자, 비밀번호, localhost를 지정하는 예를 들고 있습니다. <db_user>와 <db_passwd>는 실제 값이 아닌 placeholder이므로 그대로 실행할 설정이 아닙니다.
template 디렉터리, static, 업로드용 media와 시간대는 같은 settings.py에서 맞춥니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
TIME_ZONE = 'Asia/Seoul'
이 코드는 os와 나머지 기본 settings가 이미 있는 프로젝트 설정의 일부입니다. 독립 실행 Python 파일이 아닙니다.
기본 table과 관리자 계정을 준비하는 명령은 다음 순서입니다.
1
2
3
python manage.py migrate
python manage.py createsuperuser
python manage.py startapp bookmark
bookmark를 만든 뒤에는 반드시 INSTALLED_APPS에 등록합니다. 이 단계를 빼면 model을 작성해도 migration 대상 앱으로 인식되지 않습니다.
Model과 Admin은 왜 함께 확인해야 하나
Bookmark model에 title과 URL을 정의했다면, admin.py에서 그 class를 등록해야 관리자 화면에 나타납니다. 원문의 의도를 문법에 맞게 정리한 관리자 설정은 다음과 같습니다.
1
2
3
4
5
6
7
from django.contrib import admin
from bookmark.models import Bookmark
class BookmarkAdmin(admin.ModelAdmin):
list_display = ('title', 'url')
admin.site.register(Bookmark, BookmarkAdmin)
list_display는 Admin 목록에서 title과 URL을 보여 주는 설정입니다. 원문 초안의 class BookmarkAdmin(admin,ModelAdmin)은 점 대신 쉼표가 들어간 구조 조각이므로 그대로 복사하면 안 됩니다.
모델 변경을 database에 반영합니다.
1
2
python manage.py makemigrations
python manage.py migrate
Admin에서 데이터를 작성할 수 있다면 database와 관리자 연결까지는 성공한 것입니다. 이제 일반 화면을 위해 project URL, app URL, view, template이 남습니다.
URL에서 Template까지 끊긴 지점 찾기
project의 urls.py는 bookmark/ 요청을 앱의 bookmark.urls로 넘기고 admin/은 관리자에 연결합니다.
1
2
3
4
5
6
7
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('bookmark/', include('bookmark.urls')),
path('admin/', admin.site.urls),
]
원문 초안에서는 첫 path 뒤 쉼표가 빠져 있으므로 그대로 쓰면 목록 문법이 완성되지 않습니다. 앱에도 별도 urls.py가 있어야 하고, 그 URL이 views.py의 logic으로 이어져야 합니다.
template 경로는 다음 구조로 만듭니다.
1
2
3
4
5
mkdir templates
cd templates
mkdir bookmark
cd bookmark
vi bookmark_list.html
공통 templates를 BASE_DIR/templates로 설정했다면 실제 HTML도 그 아래 bookmark/bookmark_list.html에 있어야 합니다. 화면이 나오지 않을 때는 증상을 따라 확인합니다.
- 앱을 못 찾으면
INSTALLED_APPS를 봅니다. - table이 없으면 model 변경 뒤 migration을 했는지 봅니다.
- Admin에 model이 없으면
admin.py등록을 봅니다. - 404가 나면 project URL과 app URL의 두 단계를 봅니다.
- template 오류가 나면
DIRS와 실제 폴더 구조를 비교합니다. - 업로드 파일이나 CSS가 빠지면 media와 static 설정을 분리해 봅니다.
이 기록은 북마크 화면의 HTML과 views.py 전체 구현을 포함하지 않습니다. 따라서 게시된 조각은 완성된 CRUD 앱이 아니라 Django 파일들이 어느 순서로 연결되는지 확인하는 골격입니다.
화면 증상으로 끊긴 연결을 어떻게 찾나
404라면 요청이 view까지 도달하지 못한 경우가 먼저입니다. Project urls.py의 include, app urls.py의 path, 주소 끝의 slash를 차례로 대조합니다. View 함수에 간단한 반환이나 로그를 두어 호출 여부를 확인하면 template 문제와 URL 문제를 분리할 수 있습니다.
Template 이름 오류가 뜬다면 view는 실행된 것입니다. 이때 TEMPLATES의 DIRS, app별 template 탐색 설정, 실제 폴더와 파일명을 비교합니다. 화면은 뜨지만 목록이 비었다면 view가 queryset을 만들고 context에 담았는지, template이 같은 key로 반복하는지를 봅니다. Admin에서 데이터가 있다는 사실은 이 단계의 좋은 대조군입니다.
CSS나 업로드 이미지만 빠진 경우에는 데이터 흐름을 다시 만들지 않습니다. Static과 media의 URL, root, 개발 서버의 제공 설정을 각각 확인합니다. 이렇게 “요청 경로 → view 실행 → context → template → 자원” 순서로 한 층씩 확인해야 북마크 앱 전체를 다시 만드는 일을 피할 수 있습니다.
함께 읽으면 이해가 이어지는 글
- Django 블로그가 로컬에서는 되는데 배포에서 막힐 때: 프로젝트부터 WSGI까지 — Django 프로젝트와 blog 앱을 만들고 Post 모델, 관리자, SQLite를 연결한 뒤 PythonAnywhere WSGI 설정까지 이어지는 흐름을 정리합니다. settings.py에서 자주 빠뜨리는 앱 등록, 호스트, 정적…
- Rust Warp와 Warp 터미널은 같은 프로젝트일까? Filter 프레임워크 선택 기준 — 동명의 터미널 저장소와 Rust 웹 프레임워크가 섞인 원문을 바로잡고, warp Filter 조합의 장점, 컴파일 비용과 도입 전 확인 항목을 정리합니다.
- 비디오를 코드로 재현하면 AI의 물리 이해를 검증할까: VisPhyWorld 209장면과 백엔드 편향 — MLLM이 영상의 물리 가설을 실행 코드로 드러내는 평가법과 108개 템플릿, 209개 장면이 측정하지 못하는 범위를 짚습니다.
자주 묻는 질문
Admin에 데이터가 보이면 웹 화면 연결도 끝난 것인가요?
아닙니다. Admin은 모델과 데이터베이스 연결을 확인할 뿐입니다. 사용자 화면에는 project URL, app URL, view, template과 context가 별도로 이어져야 합니다.
Django에서 404가 나면 template부터 확인해야 하나요?
먼저 project urls.py가 app URL을 include하는지와 app의 path가 요청 주소와 맞는지 확인합니다. View에 도달하지 못한 404라면 template을 바꿔도 해결되지 않습니다.
media와 static은 왜 따로 점검하나요?
Static은 CSS, JavaScript처럼 애플리케이션이 제공하는 자원이고 media는 사용자가 올린 파일입니다. URL과 저장 경로가 다르므로 한쪽 설정으로 다른 쪽 문제를 해결할 수 없습니다.
CRUD 기능을 한꺼번에 만들지 않고 검증하는 순서
먼저 목록 읽기만 연결합니다. Admin에서 만든 북마크 한 개를 queryset으로 가져와 title과 URL을 template에 표시합니다. 이 단계가 통과하면 model, database, view, context, template의 기본 읽기 경로가 확인됩니다. Form과 삭제 기능을 동시에 넣으면 저장 오류와 렌더링 오류가 같은 화면에 섞일 수 있습니다.
다음으로 상세 화면을 추가하며 URL의 인자와 object 조회를 연결합니다. 잘못된 ID를 요청했을 때의 처리를 정하고, 목록에서 만든 링크가 같은 URL 이름을 사용하는지 봅니다. URL 문자열을 여러 곳에 직접 적기보다 이름으로 연결하면 app 경로를 바꿀 때 끊긴 위치를 줄일 수 있습니다.
생성, 수정은 입력 검증과 저장 성공을 분리합니다. 유효하지 않은 값에는 오류를 보여 주고, 저장 뒤에는 어떤 화면으로 이동하는지 확인합니다. 마지막에 삭제를 추가하고 실제 대상 ID를 다시 보여 준 뒤 처리해야 다른 객체를 지우는 실수를 줄일 수 있습니다. 이 글의 조각은 이 전체 CRUD 구현이 아니라 연결 골격이라는 범위를 유지해야 합니다.
각 단계마다 어떤 URL을 요청했고 어떤 view와 template이 선택됐는지 기록합니다. 같은 이름의 template이 여러 app에 있으면 예상과 다른 파일이 렌더링될 수 있으므로 app별 폴더 구조를 명확히 합니다. Test 데이터 몇 개로 정렬과 빈 목록 화면도 확인해야 한 건이 보인다는 사실을 전체 목록 성공으로 오해하지 않습니다.
←→ 키와 좌우 스와이프를 지원합니다. 읽던 페이지는 이 기기에 저장됩니다.