오늘의 학습 계획
_생활코딩 django 강의 2회독차(따라치기)
_튜터님이 만들어주신 파이썬 예제: 클래스 예제 다 풀기
_스파르타 django 강의 1회독차(2배속) > 2회독차(따라치기)
Django 새롭게 배운 내용
1.라우팅
_사용자가 접속하고 들어온 주소 (경로)(path)를 어디로 할당 할 지 처리하는 작업.
_사용자의 주소 입력 (http://127.0.0.1/) (http://127.0.0.1/create/) (http://127.0.0.1/read/1/) 이런 모양들 >
> myproject > urls.py > 먼저 urlpatterns 를 지정해주어야 한다. > 리스트형식으로써 안에는 라우팅과 관련된 정보가 적혀 있음. 예시는,
예시의 admin은 관리자 화면으로 이동하기 위함. 장고가 기본으로 갖고 있는 것임. 이걸 응용해서 직접 해보자 >
> 사용자가 http://127.0.0.1/ 주소를 들고 들어왔다 가정 >
> 우선 제일 먼저 project의 urls.py 파일에서 import path 뒤에 include 써서 임포트하기 >
> urlpatterns = [ ] 안에 인클루드 경로 추가.
urlpatterns = [
path('admin/', admin.site.urls)
path('', include('연결할앱이름.urls')) #연결할앱 아래에 있는 urls.py를 사용해라! 라는 뜻
]
> 프로젝트의 urls.py 파일을 복사해서 myapp에게도 urls.py 파일을 만들어줌 >
> myapp의 urls.py에서 필요 없는 것들을 지워줌
import에서 include 지워줌. 독스트링설명과 urlpatterns 리스트만 남김. >
> path()하고 받고싶은 경로들 적어줌.
from django.urls import path
urlpatterns = [
path(''),
path('create/'),
path('read/1/')
]
다 했으면 view.py 들어가서 작동될 함수를 적어주는데, 아래와 같은 형식.
from django.shortcuts import render, HttpResponse
# Create your views here.
def index(request):
return HttpResponse('Welcome!')
import에 HttpResponse 적어주는 것 중요하고, def index() 에서 인자값으로 무언가 받게 해주어야함. 관행적으로 request라고 한다.
이렇게 해 놓고 다시 myapp의 urls.py로 돌아가서 경로마다 해당하는 구체적인 함수(view에 만들어 논 것) 적어줌
from django.urls import path
from myapp import views
urlpatterns = [
path('', views.index),
path('create/', views.index),
path('read/1/', views.index)
]
이런식으로 path('경로', views.함수이름)
이렇게 부른다.
다 됐으면 브라우저에서 http://127.0.0.1:8000 접근하면 "Welcome!" 화면이 나온다. ㅎㅎㅎㅎㅎ
여기서 매우 주의할 점!!! ** 장고가 실행되고 있어야함.
어떻게 실행하냐? (윈도우+vs코드기준) 터미널에서 python manage.py runserver 명령어 치면 동작.
이거 몰라서 자꾸 왜 안되지? 하면서 views.py 갔다가 urls.py 갔다가 여기저기서 터미널에서 파이썬 파일 실행 눌러보고 난리도 아니었다 ㅋㅋㅋㅋㅋㅋㅋ
갑자기 아 ... 문득.... 하고 manage.py runserver가 떠오름
그것도 앞에 python 붙이는 것 빼먹어서 한참 고생 🤣🤣🤣 그래도 찾아내서 뿌듯하다
흐흐흐
여까지 하면 라우팅도 끝!
이 아니라
마지막으로, 계속 변화하는 주소대로 path 받는 법을 해보자.
myapp의 urls.py 파일에서 시작한다.
from django.urls import path
from myapp import views
urlpatterns = [
path('', views.index),
path('create/', views.create),
path('read/<id>/', views.read) #아까 read/1/ 이었던 곳 1 자리에 꺽쇠하고 id.
]
앞으로는 <id>자리에 무슨 숫자가 오느냐에 따라 보여주는 페이지 모습이 달라지게 될거다.
이 다음 단계는 view의 read 함수로 간다.
def read(request, id):
return HttpResponse('read'+str(id))
read 함수에서 인자값으로 id를 새롭게 받아주고,
잘 받았는지 확인할 겸, 받은 id를 활용할 겸. 출력되는 'read'문자열 뒤에 id인자로 받은 값이 따라서 출력되도록 함.
결과는
요로케 주소창에 클라이언트가 /read/2/ 라고 치면
화면에 read2가 나오고.
요로케 주소창에 클라이언트가 /read/3/ 라고 치면
화면에 read3가 나오고.
요로케 주소창에 클라이언트가 /read/99/ 라고 치면
화면에 read99가 나오고.
잘 된다.
ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ
이것으로 라우팅도 끝!
2. 장고 CRUD
오늘은 문시해알 대신 코딩테스트
_오늘의 코딩테스는 최빈값 구하기
:프로그래머스 2번 문제이지만 묘하게 난이도가 있는 친구.
def solution(array):
# 최빈값 : 주어진 array 리스트 에서 가장 자주 나오는 값.
# 여러개면 -1을 리턴.
# 딕셔너리로 하자!
# 빈 딕셔너리를 만들어서 정수배열을 하나씩 순회할 때,
# 정수를 키값으로써 딕셔너리에 추가하며 중복이 아니면 밸류를 1로 지정,
# 중복이면 밸류에 +1
# GO!
empty_dict = {} #빈 딕셔너리 만들고 #{1:1, 2:1, 3:2...+1, 4:4} 이런 식으로 추가됨
for num in array:
if num in emptry_dict:
empty_dict[num] += 1
#여기서 empty_dict[num]이란, empty_dict 안에서 for문 돌리고 있는 num을 키값으로 가지는 밸류값을 지칭.
else:
empty_dict[num] = 1
#여기까지 했으면
max_num = max(empty_dict.values())
#다만 이건 최빈값의 밸류값을 가져왔을 뿐 키값이 아니다. *사전형을 가져오는 명령은 .values() .keys() .items() 하면 리스트로 가져옴
return
여기서 맥스 넘이 나왔을 때 이게 최빈값인 줄 알았다 ㅋㅋ 사실 이건 최빈값이 아니라 최빈값 키가 가진 밸류값임.
이어서 쭉쭉 해보면,
def solution(array):
empty_dict = {} #{1:1, 2:1, 3:3, 4:1... }
for num in array:
if num in empty_dict:
empty_dict[num] += 1
else:
empty_dict[num] = 1
max_num = max(empty_dict.values()
check_list = []
# 빈 리스트를 만들고
for key_, value_ in empty_dict.items(): # for문으로 아까 만든 딕셔너리의 키와 밸류를 같이 돌린다.
if value_ == max_num: # 밸류값이 맥스넘이랑 동일하면 그의 키값을 빈 리스트에 어펜드.
check_list.append(key_) # 그러면 리스트는 키값만 가지게 됨.
print(check_list)
이렇게 하면 키값을 추려냈으니 얼추 끝났고, 마지막으로 array에서 최빈값이 여러개일 경우 -1을 리턴하도록 만드는 조건만 충족하면 된다.
def solution(array):
empty_dict = {} # {1:1, 2:1, 3:2 ... }
for num in array:
if num in empty_dict:
empty_dict[num] += 1
else:
empty_dict[num] = 1
max_num = max(empty_dict.values())
check_list = []
for key_, value_ in empty_dict.items():
if value_ == max_num:
check_list.append(key_)
if len(check_list) > 1: #만약에 최빈값이 여러개면 만들어진 리스트의 길이가 1 이상일 것이므로 랭을 쓴다.
return -1
else:
return check_list[0]
print(solution([1, 2, 3, 3, 3, 4, 4, 4, 4, 4]))
이거 풀 때 맨날 다른 사람 풀이를 봐도 len이 나오길래, 무슨 의도로 쓴 건지 몰라서 궁금했는데,
오늘 소은님이 친절하고 자세하게 알려주셔서 명확하게 알게 되었다 ㅠ
너무 감사한 소은님 👍👍👍
알게된점
_딕셔너리에서 원하는 값만 추리는 코드들 .values() .keys() .items()
_len의 영리한 사용
_리스트의 대괄호와 딕셔너리의 대괄호는 다르다는 점!!!
리스트의 대괄호는 요소들의 인덱스(번째)를 나타내고, 딕셔너리의 대괄호는 키값을 지목하여 밸류값을 불러낸다.
작은 질문들:
Q. 생활코딩 django CRUD의 Delete 파트에서 따라가며 코딩하던 중, 아래와 같은 부분에서 id 값이 None으로 잡힌다.
from django.shortcuts import render, HttpResponse, redirect
from django.views.decorators.csrf import csrf_exempt
import random
nextId = 4
topics = [
{'id':1, 'title':'routing', 'body':'Routing is...'},
{'id':2, 'title':'view', 'body':'View is...'},
{'id':3, 'title':'model', 'body':'Model is...'}
]
def HTMLTemplate(articleTag, id=None):
global topics
ol = ''
for topic in topics:
ol += f'<li><a href="/read/{topic["id"]}">{topic["title"]}</a></li>'
return f'''
<html>
<body>
<h1><a href="/">Django</a></h1>
<ul>
{ol}
</ul>
{articleTag}
<ul>
<li><a href="/create/">create</a></li>
<li>
<form action="/delete/" name="id" method="post">
<input type="hidden" name="id" value="{id}">
<input type="submit" value="delete">
</form>
</li>
</ul>
</body>
</html>
'''
def index(request):
article = '''
<h2>Welcome</h2>
Hello, Django
'''
return HttpResponse(HTMLTemplate(article))
def read(request, id):
global topics
article = ''
for topic in topics:
if topic['id'] == int(id):
article = f'<h2>{topic["title"]}</h2>{topic["body"]}'
return HttpResponse(HTMLTemplate(article, id))
@csrf_exempt
def create(request):
global nextId
if request.method == 'GET':
article = '''
<form action="/create/" method="POST">
<p><input type="text" name="title" placeholder="title"></p>
<p><textarea name="body" placeholder="body"></textarea></p>
<p><input type="submit"></p>
</form>
'''
return HttpResponse(HTMLTemplate(article))
elif request.method == 'POST':
title = request.POST['title']
body = request.POST['body']
newTopic = {"id": nextId, "title":title, "body":body}
topics.append(newTopic)
url = '/read/'+ str(nextId)
nextId = nextId + 1
return redirect(url)
@csrf_exempt
def delete(request):
global topics
if request.method == 'POST':
id = request.POST['id']
print('id', id)
newTopics = []
for topic in newTopics:
if topic['id'] != int(id):
newTopics.append(topic)
topics = newTopics
return redirect('/')
스파르타 껄로 공부한 다음에 돌아오면 여기서 부터 다시 추적할 것. 이걸로 Delete를 마치고 Update 공부해야 한다.
https://www.youtube.com/watch?v=bycMlzNMuiM&list=PLuHgQVnccGMDLp4GH-rgQhVKqqZawlNwG&index=12
12강 5분 51초 근처
>헐 미쳤다! 한참을 고민해도 안보이다가 갑자기 눈에 들어왔는데 이 부분 때문인가?
음
id 값을 지우니... 오류가 난다... 킁... 다시 None으로 적어 놓고...
복습용 키워드 메모장:
[스파르타 django]
#클라이언트 #서버
'About coding > Today I learned' 카테고리의 다른 글
2023년 04월 06일 TIL [#Django 입문_4] (0) | 2023.04.06 |
---|---|
2023년 04월 05일 TIL [#Django 입문_3] (1) | 2023.04.06 |
2023년 4월 3일 TIL [#Django 입문_1] (0) | 2023.04.03 |
2023년 03월 31일 TIL (0) | 2023.03.31 |
2023년 03월 30일 TIL (0) | 2023.03.30 |