Link
09-25 13:23
«   2020/09   »
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30      
Archives
Today
939
Total
1,023,685
관리 메뉴

꿈 많은 사람의 이야기

Django로 todo list web 개발하기 - 2편. mysql 연동, 페이지 생성(view, template, static) 본문

python-django

Django로 todo list web 개발하기 - 2편. mysql 연동, 페이지 생성(view, template, static)

이수진의 블로그 이수진의 블로그 2019. 5. 20. 20:07

완성된 코드는 아래 github 주소에 있습니다!

도움이 되셨다면 좋아요와 깃허브 스타를 눌러주세요! 저에게 있어 큰 힘이 됩니다 ㅠㅠhttps://github.com/lsjsj92/django_todo_app

 

지난번 포스팅에서 django를 설치하고 앱을 생성하고, 데이터베이스 migrate도 해보았습니다.

그리고 admin user를 만들었죠

이번 포스팅은 이제 실제 웹 페이지를 띄우도록 합니다

view와 template부분, static 부분을 연동하는 과정을 진행합니다.

todo list 게시판을 만들기 위한 전초 작업입니다.

사실.. django로 게시판 만들기와 같다고 생각하시면 됩니다.

 

 

저는 먼저 static 폴더를 하나 만들었습니다. todo_main에 디렉토리를 하나 만들어서 그 밑에 css, js를 만들고

그 아래에 필요한 라이브러리 파일을 넣었습니다.

sortable.js는 마우스 드래그를 통해 게시판 목록을 섞을 수 있는 js이고, css에 들어간 것은 부트스트랩(bootstrap)을 활용하기 위한 css 파일입니다.

css는 저 파일들이 다 필요하지 않습니다. 부트스트랩만 적용이 되면 됩니다!

위 파일들은 구글링을 통해 받을 수 있습니다. 그리고 굳이 iso.css, animate.css 이게 다 필요는 없습니다.

단지, 부트스트랩만 되면 됩니다

 

 

그리고 todoSubject의 프로젝트 폴더에 들어가서 settings.py를 확인합니다.

 

 

여기에서 저희가 추가했던 app을 추가해줍니다. INSTALLED_APPS에다가 추가해주시면 됩니다

 

 

그리고 밑에 LANGUAGE_CODE와 TIME_ZONE, STATIC_URL, MEDIA_URL 등을 설정해줍니다.

언어는 당연히 한국이 되어야 하구요. static파일과 media 파일이 어디로 들어갈지 경로를 설정해주는 것입니다.

 

 

 

그리고 아까 todo_main -> static 디렉토리에 넣었던 자료들이 적용되게 하기 위하여

python manage.py collectstatic을 진행합니다

 

 

그러면 위와 같이 todo_main이 아닌 프로젝트 제일 상위 디렉토리 아래에 static이 만들어진 것을 볼 수 있습니다.

 

 

다음은 다시 settings.py에 가서 mysql과 연동하기 위한 설정을 진행합니다.

pymysql이 설치되어 있으셔야 합니다.

pip install pymysql로 간단히 설치가 가능합니다

 

 

그리고 데이터베이스 설정값을 넣어줍니다.

 

저 데이터베이스 NAME 그대로 사용하실 필요가 없습니다.

여러분들이 사용하시는 설정으로 바꾸시면 되세요!

저도 사진으로는 programmers_subjects라고 나와있지만, 실제로는 todo_app 으로 명명했습니다.

 

mysql을 사용하기에 mysql과 관련된 설정을 하고 db이름, db계정, 비밀번호, db호스트 등의 정보를 넣어줍니다.

아직 사용하지는 않습니다. 하지만, DB 정보는 있어야 하기 때문에 DB는 만들어두세요!

 

자 이제 django와 mysql 연동이 되었습니다.

이제 본격적으로 project와 app을 연동해보죠

 

todoSubject의 프로젝트 폴더로 들어가면 urls.py가 있습니다

 

 

이 부분을 위와 같이 수정합니다.

만약 localhost:8000/ 으로 들어오면 todo_main.urls에 연동시키겠다

만약 localhost:8000/index으로 들어오면 todo_main.urls에 연동시키겠다 이런 뜻입니다

그러면 todo_main.urls에서 받을 준비를 해야겠죠?

 

 

여기도 마찬가지로 urls.py를 만들어줍니다. 여기는 처음에는 없을겁니다. 만들어주시면 됩니다

 

 

그리고 위와 같이 만들어줍니다.

만약 todo_main으로 localhost:8000 패턴으로 오게 된다면(r'^$') Todo_main.as_view 행동을 취해라! 이런 뜻입니다.

그러면 Todo_main은 어딨을까요?

이 부분은 view에서 설정해줍니다

 

 

view.py에 가셔서 generic view를 통해 페이지를 만들어줍니다.

django에서는 function based view와 generic view 크게 2가지 형태의 view 개발이 있습니다.

function based view는 사용자가 세세하게 코딩할 부분이 있으면 사용합니다.

generic view는 간편하게 사용할 수 있고 코드가 매우 간결하고 단순합니다.

저는 이 generic view와 function based view를 섞으면서 진행할 것입니다. 필요에 따라서 나뉠 것입니다!

아무튼 저렇게 하면 Todo_main에는 TemplateView(일반적인 view)를 보여주는데 get 방식으로 받았을 때는

todo_main/index.html 로 이동하라! 라는 것입니다

 

 

그러면 todo_main에 index.html을 만들어줘야겠죠

templates라는 디렉토리를 만들고 그 밑에 todo_main 폴더를 하나 더 만들고 그 아래에 index.html을 만들어줍니다

 

 

그리고 위와 같이 내용을 아무렇게나 사용하고

python manage.py runserver를 가동!

 

 

이렇게 나오게 됩니다

이번 포스팅은 여기까지입니다!

35 Comments
  • 프로필사진 토마스 2019.06.12 11:26 좋은 글 감사합니다. 완전 생 초보라 기간이 좀 지난 강의들은 코딩도 다르고 프로그램도 다 달라서 엄청 헤맸는데 최신글이라 이번에는 가능할 것 같네요 ^ㅠ^ 그런데 어디서 오류가 난건지 잘 안되서 처음부터 다시 해봐야겠어요
  • 프로필사진 이수진의 블로그 이수진의 블로그 2019.06.12 11:37 신고 안녕하세요 ㅎㅎ 감사합니다

    만약 장고가 처음이시면 장고걸스도 추천드립니다~ 그쪽이 더 초보자 입장에서 사용하기 쉬우실 겁니다!
  • 프로필사진 토마스 2019.06.12 12:27 ㅠㅜ 여기는 아직 저에겐 이른 곳인 가봐요 장고걸스 정복 후 다시 돌아오겠습니다.
  • 프로필사진 이수진의 블로그 이수진의 블로그 2019.06.12 12:41 신고 넵 ㅎㅎ 거기서 배우시면 여러가지 이론 적인 내용도 익히실 수 있으실 겁니다!
    화이팅입니다
  • 프로필사진 늅늅이 2019.07.25 22:21 안녕하세요. 따라하던 중에 인덱스html을 추가하고 서버를 실행하니django.db.utils.OperationalError: (2003, "Can't connect to MySQL server on '127.0.0.1' ([WinError 10061] 대상 컴퓨터에서 연결을 거부했으므로 연결하지 못했습니다)") 이런 에러가 뜨는데 어떻게 해결해야하나요??
  • 프로필사진 이수진의 블로그 이수진의 블로그 2019.07.25 22:29 신고 안녕하세요 ~
    혹시 mysql 설정이 잘못되었거나 mysql이 실행중이 맞으신가요??그걸 확인해 보셔야 할 것 같아요
  • 프로필사진 늅늅이 2019.07.25 22:57 django.db.utils.InternalError: (1049, "Unknown database 'programmers_subject'")

    mysql을 실행해서 연결 오류는 사라졌지만 위의 오류가 나타나는데 mysql의 처음있는db이름을 programmers_subject로 바꿔야하는건가요?
  • 프로필사진 이수진의 블로그 이수진의 블로그 2019.07.26 10:45 신고 안녕하세요!
    데이터 베이스 이름은 늅늅이님이 원하시는 이름으로 바꾸시면 됩니다 ㅎㅎ

    DB 설계는 따로 하시고 이름을 맞게 바꾸시면 되는것이죠!
    굳이 저 이름대로 따라하실 필요는 없습니다.
  • 프로필사진 늅늅이 2019.07.26 13:13 아 해결했습니다 mysql은 안써봐서 구글링을 해보니 create database programmers_subject로 해서 만드니까 연동 됫습니다 답변 감사합니다.
  • 프로필사진 이수진의 블로그 이수진의 블로그 2019.07.26 14:11 신고 넵 ㅎㅎ 다행이네요~
  • 프로필사진 duddnd 2019.08.05 16:54 mysql은 이렇게 하면되는데 pymysql.install_as_mysqldb()
    오라클은 어떻게 쓰면 될까여??
  • 프로필사진 이수진의 블로그 이수진의 블로그 2019.08.05 17:10 신고 검색해보니 오라클은 해당 문장이 필요하지 않은것 같습니다.

    데이터베이스 설정부분에서 django.db.backends.oracle 로 하면 되는 것 같네요 ㅎㅎ
  • 프로필사진 duddnd 2019.08.05 17:18 C:\Users\user\Desktop\todolist\todoSubject>python manage.py runserver
    Watching for file changes with StatReloader
    Performing system checks...

    Exception in thread django-main-thread:
    Traceback (most recent call last):
    File "C:\Python37\lib\threading.py", line 917, in _bootstrap_inner
    self.run()
    File "C:\Python37\lib\threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
    File "C:\Python37\lib\site-packages\django\utils\autoreload.py", line 54, in wrapper
    fn(*args, **kwargs)
    File "C:\Python37\lib\site-packages\django\core\management\commands\runserver.py", line 117, in inner_run
    self.check(display_num_errors=True)
    File "C:\Python37\lib\site-packages\django\core\management\base.py", line 390, in check
    include_deployment_checks=include_deployment_checks,
    File "C:\Python37\lib\site-packages\django\core\management\base.py", line 377, in _run_checks
    return checks.run_checks(**kwargs)
    File "C:\Python37\lib\site-packages\django\core\checks\registry.py", line 72, in run_checks
    new_errors = check(app_configs=app_configs)
    File "C:\Python37\lib\site-packages\django\core\checks\urls.py", line 40, in check_url_namespaces_unique
    all_namespaces = _load_all_namespaces(resolver)
    File "C:\Python37\lib\site-packages\django\core\checks\urls.py", line 57, in _load_all_namespaces
    url_patterns = getattr(resolver, 'url_patterns', [])
    File "C:\Python37\lib\site-packages\django\utils\functional.py", line 80, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
    File "C:\Python37\lib\site-packages\django\urls\resolvers.py", line 579, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
    File "C:\Python37\lib\site-packages\django\utils\functional.py", line 80, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
    File "C:\Python37\lib\site-packages\django\urls\resolvers.py", line 572, in urlconf_module
    return import_module(self.urlconf_name)
    File "C:\Python37\lib\importlib\__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
    File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
    File "<frozen importlib._bootstrap>", line 983, in _find_and_load
    File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
    File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
    File "<frozen importlib._bootstrap_external>", line 728, in exec_module
    File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
    File "C:\Users\user\Desktop\todolist\todoSubject\todoSubject\urls.py", line 27, in <module>
    path('board/', include('todo_board.urls')),
    File "C:\Python37\lib\site-packages\django\urls\conf.py", line 34, in include
    urlconf_module = import_module(urlconf_module)
    File "C:\Python37\lib\importlib\__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
    File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
    File "<frozen importlib._bootstrap>", line 983, in _find_and_load
    File "<frozen importlib._bootstrap>", line 965, in _find_and_load_unlocked
    ModuleNotFoundError: No module named 'todo_board.urls'

    Traceback (most recent call last):
    File "manage.py", line 21, in <module>
    main()
    File "manage.py", line 17, in main
    execute_from_command_line(sys.argv)
    File "C:\Python37\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
    utility.execute()
    File "C:\Python37\lib\site-packages\django\core\management\__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
    File "C:\Python37\lib\site-packages\django\core\management\base.py", line 323, in run_from_argv
    self.execute(*args, **cmd_options)
    File "C:\Python37\lib\site-packages\django\core\management\commands\runserver.py", line 60, in execute
    super().execute(*args, **options)
    File "C:\Python37\lib\site-packages\django\core\management\base.py", line 364, in execute
    output = self.handle(*args, **options)
    File "C:\Python37\lib\site-packages\django\core\management\commands\runserver.py", line 95, in handle
    self.run(**options)
    File "C:\Python37\lib\site-packages\django\core\management\commands\runserver.py", line 102, in run
    autoreload.run_with_reloader(self.inner_run, **options)
    File "C:\Python37\lib\site-packages\django\utils\autoreload.py", line 587, in run_with_reloader
    start_django(reloader, main_func, *args, **kwargs)
    File "C:\Python37\lib\site-packages\django\utils\autoreload.py", line 572, in start_django
    reloader.run(django_main_thread)
    File "C:\Python37\lib\site-packages\django\utils\autoreload.py", line 290, in run
    self.run_loop()
    File "C:\Python37\lib\site-packages\django\utils\autoreload.py", line 296, in run_loop
    next(ticker)
    File "C:\Python37\lib\site-packages\django\utils\autoreload.py", line 336, in tick
    for filepath, mtime in self.snapshot_files():
    File "C:\Python37\lib\site-packages\django\utils\autoreload.py", line 352, in snapshot_files
    for file in self.watched_files():
    File "C:\Python37\lib\site-packages\django\utils\autoreload.py", line 251, in watched_files
    yield from iter_all_python_module_files()
    File "C:\Python37\lib\site-packages\django\utils\autoreload.py", line 103, in iter_all_python_module_files
    return iter_modules_and_files(modules, frozenset(_error_files))
    File "C:\Python37\lib\site-packages\django\utils\autoreload.py", line 138, in iter_modules_and_files
    if not path.exists():
    File "C:\Python37\lib\pathlib.py", line 1339, in exists
    self.stat()
    File "C:\Python37\lib\pathlib.py", line 1161, in stat
    return self._accessor.stat(self)
    OSError: [WinError 123] 파일 이름, 디렉터리 이름 또는 볼륨 레이블 구문이 잘못되었습니다: '<frozen importlib._bootstrap>'

    C:\Users\user\Desktop\todolist\todoSubject>

    어디가 잘못된지 모르겟어용 혹시 제가 빠뜨린부분이 있는건가용 ㅠ
  • 프로필사진 이수진의 블로그 이수진의 블로그 2019.08.05 21:28 신고 ModuleNotFoundError: No module named 'todo_board.urls'

    이라는 에러가 있네요
    urls를 추가해주셔야 합니다.
    그리고 이 url을 연동해주셔야하구요~
  • 프로필사진 이수진의 블로그 이수진의 블로그 2019.12.26 15:31 신고 감사합니다 ~
  • 프로필사진 susu1012 2019.09.05 17:46 포스팅에서는 todo_main.urls 에만 생성을 해주고 끝내셔서 그러신거 같아요
    todoSubject에 urls.py 파일에
    # board app
    path('board/', include('todo_board.urls')),
    이부분 때문에 에러가 나시는거 같네요
    해당 path 부분 주석 하시고 해보세요
  • 프로필사진 이수진의 블로그 이수진의 블로그 2019.09.05 22:35 신고 지적해주셔서 감사합니다 ㅠㅠ
  • 프로필사진 반니루니 2019.12.23 17:54 신고 django 2.1 버전이신거죠?

    2.0 이후로는 url > path 로 변경되고 r'^$' 정규식들은 '경로'로 바뀐것같은데 2.2부터 바뀐건지 헷갈리네요.

    아무튼 좋은 포스팅 감사합니다^^ 처음접하시는 분들은 에러코드 많이 검색하셔야 할듯 싶네요!
  • 프로필사진 이수진의 블로그 이수진의 블로그 2019.12.23 21:29 신고 넹 저는 그냥 저렇게 구현해봤습니다 ㅎㅎ 예전부터 저게 편했어요 ~
    감사합니다. 에러코드.. 안접하게 자세히 썻어야했네요 ㅠㅠ
  • 프로필사진 반니루니 2019.12.24 16:07 신고 아니에요 울지마세요.

    좋은 블로그와 글입니다^^ 그정도는 충분히 검색하셔서 사용하실수 있을거에요.

    좋은 글 감사합니다!
  • 프로필사진 이수진의 블로그 이수진의 블로그 2019.12.26 15:29 신고 감사합니다. 다음엔 좀 더 자세히 쓰겠습니다 ~
  • 프로필사진 w0w6w4@gmail.com 2019.12.26 16:05 Todo_board 에러 해결 방법. (Todo_list와 유사하게 해결해주면 됩니다. 이거 안해주면 다음장에서도 막힙니다.)


    - 2장에서는 우선 todoSubject의 urls.py에 있는 path('board/', include('todo_board.urls'))를 #을 이용하여 비활성화 해줍니다.


    - 3장 내용을 쭉 따라 하신후 마지막에 비활성화 했던 path('board/', include('todo_board.urls'))를 다시 살려주시고 다음을 진행합니다.

    (header 부분은 github에서 복붙하기!{% endblock main %}과 </html> 사이에 있는 부분은 삭제)

    1. todo_board에 urls.py 파일을 만들어 줍니다. 그리고 아래 내용을 붙여 넣습니다.

    from django.conf.urls import url, include
    from . import views
    from django.conf import settings
    from django.conf.urls.static import static
    app_name = 'todo_board'
    urlpatterns = [
    url(r'^$', views.Todo_board.as_view(), name='todo_board'),
    ]
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

    2. todo_board에 있는 views.py에도 다음을 붙여넣습니다.

    from django.shortcuts import render, redirect
    from django.views import generic

    class Todo_board(generic.TemplateView):
    def get(self, request, *args, **kwargs):
    template_name = 'todo_board/todo_board_list.html'
    return render(request, template_name)

    3. todo_boad 폴더 아래에 templates폴더를 만들고 그 밑에 todo_board를 만든 뒤, 그 안에 todo_board_list.html 파일을 만듭니다. 파일안에 다음 내용을 넣습니다.
  • 프로필사진 이수진의 블로그 이수진의 블로그 2019.12.26 17:22 신고 w0w6w4 님 감사합니다 ^^
    저보다 더 잘아시는 것 같네요.
    덕분에 다른 분들께 많은 도움이 될 것 같습니다
  • 프로필사진 w0w6w4@gmail.com 2019.12.26 16:08 {% extends 'todo_main/common/header.html' %}
    {% load staticfiles %}
    {% block main %}

    <div class="alert alert-info">
    <strong>마감이 지난 일정!</strong> {{ over_end_day }}
    </div>
    <div class="alert alert-info">
    <strong>마감이 가까운 일정!</strong> {{ close_end_day }}
    </div>
    {% endblock main %}

    우선 이렇게 대충 오류 넘기시고, 블로거님 글대로 쭉 진행하시다보면 원래 의도대로 수정될 수 있을거에요~
  • 프로필사진 이수진의 블로그 이수진의 블로그 2019.12.26 17:22 신고 감사합니다 ~~!
  • 프로필사진 w0w6w4@gmail.com 2019.12.27 10:36 너무 겸손하시네요 ㅋㅋ 저도 수진님 글 보고 배우려고 들어왔어요 ㅎㅎ 개발은 처음이에요^^
  • 프로필사진 이수진의 블로그 이수진의 블로그 2019.12.27 12:58 신고 그러시군요 ㅎㅎ 부디 도움이 되시길 바랍니다 ~ 궁금하신 것 있으시면 편하게 댓글 남겨주세요 ~
  • 프로필사진 hayoung 2020.01.20 15:05 튜토리얼 빈틈없이 따라했는데 계속 'AttributeError: module 'pymysql' has no attribute 'install_as_MYSQLdb' 이런 에러가 뜨네요 ㅠㅠ 어떻게 하면 좋을까요?
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.01.20 22:10 신고 안녕하세요~
    pymysql을 설치하셔야합니다.
    pip install pymysql로 패키지 설치하시면 됩니당!
  • 프로필사진 kkddhh2826@gmail.com 2020.02.02 17:27 혹여나 저같이 migrate에서 에러코드 2059뜨신다면...

    버전 8.04 MySQL부터는 이전버전서의 mysql_native_password방식 대신 caching_password를 기본 인증 플러그인으로 사용해서 기존의 mysql_native_password인증을 예상하는 이전 서비스와 호환성 문제가나서 이러한 에러가 난다고 합니다.
    (출처: https://stackoverflow.com/questions/50469587/django-db-utils-operationalerror-2059-authentication-plugin-caching-sha2-pas)
    해결방법으로는 mysql 버전을 다운그레이드하거나,
    저같이 mysqld에서
    ALTER USER '접속할 유저이름'@'ip_address정보' IDENTIFIED WITH mysql_native_password BY '비밀번호';
    를 입력해주면 에러를 해결할 수 있습니다. (굳이 이런 글을 남기냐면, 이거 찾느라 좀 삽질좀 했어서;;)
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.02.02 20:52 신고 안녕하세요.
    너무 감사합니다.
    이런 댓글 하나가 다른 분들에게, 또 저에게 큰 도움이 됩니다.
    감사드립니다 !!
  • 프로필사진 hgo99 2020.09.16 23:19 WARNINGS:
    ?: (2_0.W001) Your URL pattern '^$' [name='todo_main'] has a route that contains '(?P<', begins with a '^', or ends with a '$'. This was likely an oversight when migrating to django.urls.path().
    ?: (2_0.W001) Your URL pattern '^$' [name='todo_main'] has a route that contains '(?P<', begins with a '^', or ends with a '$'. This was likely an oversight when migrating to django.urls.path().
    ?: (2_0.W001) Your URL pattern '^$' [name='todo_main'] has a route that contains '(?P<', begins with a '^', or ends with a '$'. This was likely an oversight when migrating to django.urls.path().
    ?: (urls.W005) URL namespace 'todo_main' isn't unique. You may not be able to reverse all URLs in this namespace

    System check identified 5 issues (0 silenced).

    이렇게 에러가 떴는데 혹시 도움 받을 수 있을까요...?ㅠㅠ...
    mysql 관련 부분에서 잘못한 것 같은데 user랑 password post 전부 제대로 적은 것 같은데 ... 어떻게 해결해야할지 모르겠어요
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.09.18 09:54 신고 안녕하세요.

    에러를 보니까 todo_main이 unique하지 않다고 나오네요.
    django 프로젝트에서 todo_main이 겹치는 부분이 있는 것 같습니다.
    mysql 문제가 아닌 것 같아요.
  • 프로필사진 hgo99 2020.09.18 17:27 감사합니다. 덕분에 해결했어요 :)

    한가지 궁금한게 있는데 class Todo_main에서 변수 template_name이 UnboundLocalError가 발생하길래
    return render(request, template_name) 이 아니라
    return render(request,'todo_main/index.html')로 바꾸었습니다. 이렇게 사용해도 괜찮을까요? 좋은 글 써주셔서 감사합니다.
  • 프로필사진 이수진의 블로그 이수진의 블로그 2020.09.18 21:40 신고 아 다행이네요 ㅎㅎ
    네 그렇게 쓰셔도 크게 상관없습니다 ~
댓글쓰기 폼