[Django 06] SQLite 모델 만들기

이제 모델을 만들겁니다.

장고 프로젝트 폴더로 이동합니다.
아래 명령어를 실행합니다.
마이그레이트를 하는건데, 기본 설정을 잡아주는것으로 알고 있습니다.

python3 manage.py migrate

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  No migrations to apply.

모델 만들기

모델 : 부가적인 메타데이터를 가진 데이터베이스의 구조(layout)
– 데이터에 관한 단 하나의, 가장 확실한 진리의 원천.
장고는 DRY(Dont Repeat Yourself) 원칙을 따름
http://wiki.c2.com/?DontRepeatYourself

Question과 Choice 모델을 만들거고, Question은 질문과 일자를 가지고 있을 겁니다.
Choice는 두개의 필드를 가집니다.(the text of the choice and a vote tally). 각 Choice는 Question과 관련있습니다.

polls/models.py 파일을 생성합니다.

from django.db import models

# 모델의 활성화
# 앱을 위한 데이터베이스 스키마 생성(CREATE TABLE)
# Question과 Choice 객체에 접근하기 위한 Python 데이터베이스 접근 API 생성

# 현재 프로젝트에게 polls 앱이 설치 되었다는것을 알려야 한다. (앱을 꼈다 뺐다 할수 있다.)
# 앱을 현재의 프로젝트에 포함시키기 위해서는 settings.py > INSTALLED_APPS 설정에 추가해야 한다. 
# PollsConfig 클래스는 polls/apps.py 파일 내에 존재 -> polls.apps.PollsConfig




# django.db.models.Model subclass
# 데이터베이스의 각 Field는 클래스의 인스턴스로 표현
    
# 각 필드 
# CharField는 문자 필드
# DateTimeField는 날짜와 시간(datetime) 필드 등

# 각 필드의 인스턴스 이름(question_text)은 
# 기계가 읽기 좋은 형식(machine-friendly format)의 데이터베이스 필드 이름은
# 필드명을 Python 코드에서 사용할 수 있으며, 데이터베이스에서는 컬럼명으로 사용 

# 필드 클래스의 생성자에 선택적인 첫번째 위치 인수를 전달하여 사람이 읽기 좋은(human-readable)
# 이름을 지정할 수도 있다. -> Question.pub_date

# 몇몇 Field 클래스는 인수가 필요합니다. (CharField의 경우 max_length)
# Field는 다양한 선택적 인수들을 가질수 있다.
class Question(models.Model):    
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

#  ForeignKey를 사용한 관계설정
#  각각의 Choice가 하나의 Question에 관계된다는 정보.
#  question = models.ForeignKey(Question, on_delete=models.CASCADE)
class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

위와 같은 코드를 작성하고 다음 명령을 통해 변경시킨 모델을 migration으로 저장하고 싶다고 장고에게 알려준다.

python3 manage.py makemigrations polls

-> 결과
Migrations for 'polls':
  polls/migrations/0001_initial.py
    - Create model Question
    - Create model Choice

잘 보면 polls 밑에 migrations 폴더와 0001 이름의 모델이 생성되었다.

아래 코드를 실행해보면, 내부적으로 어떤 SQL 문장이 실행되는지 알수 있다.

python3 manage.py sqlmigrate polls 0001

-> 결과테테테ㅌ
BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "question_text" varchar(200) NOT NULL, "pub_date" datetime NOT NULL);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL, "question_id" integer NOT NULL REFERENCES "polls_question" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");
COMMIT;

테이블 이름은 앱 이름 + _ + 모델의 이름으로 자동 생성한다.
기본키 id도 자동 생성되고, 재지정이 가능하다.
외래 키 필드명에 “_id” 이름이 자동으로 추가된다. (재지정 가능)

python manage.py migrate

migrate 명령은 아직 적용되지 않은 마이그레이션을 모두 수집해 이를 실행하며(Django는 django_migrations 테이블을 두어 마이그레이션 적용 여부를 추적한다), 이 과정을 통해 모델에서의 변경 사항들과 뎅터베이스의 스키마의 동기화가 이루어진다.

마이그레이션은 매우 기능이 강력하여, 데이터베이스나 테이블을 수정하지 않고 모델의 반복적인 변경을 가능하게 해준다. 동작중인 데이터베이스를 자료 손실없이 업그레이드 하는 데 최적화 되어 있다.

모델의 변경을 만드는 세단계의 지침

1. (moles.py에서) 모델을 변경
2. python manage.py makemigrations 
 -> 변경사항에 대해 마이그레이션을 만듬
3. python manage.py migrate
 -> 변경 사항을 데이터베이스에 적용

manage.py 유틸리티로 어떤 일들을 할 수 있는지 django-admin 문서를 읽어보세요.

[Django 03] include()와 path()

REST API를 쓰고 싶다는 생각이였는데, 어쩌다보니 장고로 들어와버렸다.
파이썬을 공부하다보니 자연스럽게 흘러들어왔는데, 초보이지만 나름 정리를 하면서 내용을 공유하고 싶어서 글을 작성한다.

내용은 튜토리얼을 정리한 수준이다.

어느정도 시간이 지나고 나면 좋은 글이 나올수도 있겠지..

"""mysite URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    # 최상위 URL에서 polls.urls 모듈을 바라보게 설정
    # include() 함수는 다른 URLconf들을 참조할 수 있도록 도와준다.
    # - URL의 그 시점까지 일치하는 부분을 잘라내고, 
    # 남은 문자열 부분을 후속 처리를 위해 include된 URLconf로 전달

    # path()는 route와 view, kwargs, name을 사용 가능
    # - route : URL 패턴을 가진 문자열. 일치하는 패턴을 찾을 때 까지 요청된 URL을 
    #   각 패턴과 리스트의 순서대로 비교한다.
    #   패턴들은 GET이나 POST의 매개 변수들, 혹은 도메인 이름을 검색하지 않는다.
    #   https://www.example.com/myapp/이 요청될 경우, URLconf는 myapp/만 바라본다.
    #   https://www.example.com/myapp/?page=3 이 요청될 경우에도 myapp/만 신경쓴다.
    # - view 
    #   일치하는 패턴을 찾으면, HttpRequest 객체를 첫번째 인수로 하고, 경로로부터 <캡쳐된> 값을
    #   키워드 인수로 하여 특정한 view 함수를 호출
    # - kwargs
    #   view에 전달될 사전형 데이터
    # - name 
    #   URL에 이름을 지으면, 템플릿을 포함한 어디서나 명확하게 참조할 수 있다.
    #   이 강력한 기능을 통해, 단 하나의 파일만 수정해도 project내의 모든 URL 패턴을 바꿀 수 
    #   있도록 도와준다.
    path('polls/', include('polls.urls')),
    path('admin/', admin.site.urls),
]

[Django 02] 시놀로지 도커에 설치하기

1. 터미널에서 apt update를 한다

역시나 내가 뭘 하면 오류가 발생하지. 도커를 내렸다 올리면 해결된다.

apt upgrade
apt update

2. python3.8 설치를 한다.

apt install python3.8

3. pip 설치를 한다.

apt install python3-pip
pip3 --version
pip3 install --upgrade pip

pip3 –version 명령어를 쳐서 python 몇 버전과 연결이 되어 있는지 확인한다.
현재 사용하는 파이썬 버전은 3.8.3인데, 3.6과 연결되어 있다. 이를 조치해주려 한다…

파이썬 제거하기..

sudo apt purge -y python2.7-minimal
sudo apt-get remove --purge python3.6

분명히 삭제했음에도 삭제가 되지 않는 현상이 있다면,

sudo apt autoremove

깔끔하게 제거되었다. ㄲㄲㄲ
다시 1번부터 재설치..

3. Django install

pip3 install Django

장고 실행은 아래글을 참고

[Django 01] 장고를 설치해보자.

실행방법

sudo python3 manage.py rumserver 0:포트번호

오류 발생 – Allowed Host

ALLOWED_HOSTS = [‘magpiebros.com’]


	

[Django 01] 장고를 설치해보자.

목표: restAPI를 제공할 수 있는 서버를 만드는 것이 목표이다.

이를 위해서는 웹서버가 필요하다.
Flask와 고민해보았으나, Django를 선택했다.

먼저 우분투 서버로 들어가서 다음과 같이 장고를 인스톨한다.

sudo python3 -m pip install Django

이제 튜토리얼을 따라서 샘플을 만들어보아야 겠다.
/var/www/html/로 이동해서 다음 명령을 실행한다.

sudo django-admin startproject mysite

다음과 같이 앱을 실행하면, html 폴더 이하에 해당 mysite 폴더가 생성된다.
해당 폴더에는 관련 소스들이 생성된다.
django나 test를 사용하여 프로젝트를 생성한다면 오류가 발생할 수 있으니 주의.

  • 관련글 : 학습해야 할 목록
  • https://docs.djangoproject.com/en/3.1/ref/django-admin/
  • https://docs.python.org/3/tutorial/modules.html#tut-packages
  • https://docs.djangoproject.com/en/3.1/topics/http/urls/

서버를 구동시켜보자

sudo python3 manage.py runserver

그리고, 웹 브라우저로 접속해보자

장고 웹 서버를 구동시켰다.
오늘의 목표는 여기까지.

[Python] webdriver.Chrome(‘chromedriver’) 에러 대처

난 단지 selenum을 학습하고 싶었을뿐인데, 예외가 발생했다.
물론, 크롬의 버전을 확인했고, 크롬드라이버도 해당 버전에 맞추어 설치했음에도 불구하고 이런 사태가 벌어졌다.

from selenium import webdriver

driver = webdriver.Chrome('chromedriver')

에러내용은 아래와 같았다.


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/-/Documents/dev/Python/webscraping_basic/13_selenium.py", line 3, in <module>
    driver = webdriver.Chrome('chromedriver')
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/chrome/webdriver.py", line 73, in __init__
    self.service.start()
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/selenium/webdriver/common/service.py", line 81, in start
    raise WebDriverException(
selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home

몇가지 해결책들이 있었지만, 우선 정품상태를 좋아하기 때문에 커맨드로 뭔가 땡겨오는 것들은 선호하지 않아서 크롬을 일단 최신버전으로 업그레이드 해보기로 했다.

다시 드라이버를 설치해보고, 증상이 동일하길래 에러문구를 자세히 보았다…
아무리봐도 ./ 패스가 맞는데도 동작을 안하길래 절대경로로 실행 시켰더니 잘 동작하였다.

왜 상대경로로 동작을 하지 않았을까?

문제는 경로 문제였음.

from selenium import webdriver

driver = webdriver.Chrome('/Users/-/Documents/dev/Python/webscraping_basic/chromedriver')  # Optional argument, if not specified will search path.

[Python] tkinter -02. 버튼 생성

  • 하단에 참고 링크를 보면, 더 좋은 강좌들이 많다. “나도코딩”이라는 분의 강좌를 기반으로 내가 원하는대로 글을 작성할 예정이다.

윈도우 생성만 하기에는 글이 너무 아쉬워서 버튼생성부까지 글을 작성하려고 한다.
바로 바로 실행해서 화면을 볼수 있기 때문에, 너무 즐거운 코딩이다.

파일명은 원하는데로 만들되, 확장자는 .py로 만들것.
동영상에서는 윈도우로 개발하기 때문에, 배경색이 설정되지만, Mac에서는 배경색이 지정되지 않는다.

from tkinter import *

root = Tk()
# 타이틀 설정
root.title("GUI Python")

# 윈도우 크기 설정
# root.geometry("640x480")    # 가로 * 세로
# root.geometry("640x480+100+200")    # 가로 * 세로 + x좌표 + y좌표
root.geometry("640x480+800+200")    # 가로 * 세로 + x좌표 + y좌표

# 윈도우 크기 변경
# root.resizable(False, False) # x(너비), y(높이) 값 변경 허용

# 버튼 생성
btn1 = Button(root, text="버튼1")
btn1.pack()

# 버튼에 x, y축에 패딩을 넣는 방법
# 글자수만큼 늘어난다.
btn2 = Button(root, padx=50, pady=10, text="버튼2")
btn2.pack()

# 버튼에 넓이와 높이를 강제 지정하는 방법
btn4 = Button(root, width=10, height=3, text="버튼4")
btn4.pack()

# mac에서 bg color가 지원되지 않는다.
# btn5 = Button(root, fg="red", bg='yellow', text="버튼5")
# btn5.pack()

# 버튼 터치 이벤트 함수
def btncmd():
    print("버튼이 클릭되었습니다.")

# 이미지 버튼에 삽입
photo = PhotoImage(file="image/apple.png")
btn6 = Button(root, image=photo, command=btncmd)
btn6.pack()

root.mainloop() 

좀더 하고 싶지만, 오늘은 여기까지만..
궁금하다면 즐겨찾기를 해주시고, 자주 놀러와주세요.

  • 참고 링크
  • https://www.youtube.com/watch?v=bKPIcoou9N8&t=3723s

[Python] tkinter -01. 윈도우 생성

파이썬 강좌를 찾아보던중 좋은 강좌가 있어서 해당 내용을 작성해 본다.

tkinter 라이브러리를 통해 GUI 환경 개발을 진행할것이다.
맨날 문법만 공부하거나, 마땅히 응용할게 없다면 GUI부터 익혀서 응용해보자.
(하단에 참고 링크를 보면, 더 좋은 강좌들이 많다. “나도코딩”이라는 분의 강좌를 기반으로 내가 원하는대로 글을 작성할 예정이다.)

GUI를 어느정도 학습하고 나면 좀더 재미있는 것들을 진행해보겠다.
파이썬으로 기본 윈도우를 띄우는 코드이다.

window_test.py 로 작성해서 실행해 볼 것.
코드는 간단하니 부가적인 설명은 생략.

from tkinter import *

root = Tk()
# 타이틀 설정

root.title("GUI Python")

# 윈도우 크기 설정
root.geometry("640x480") # 가로 * 세로
# root.geometry("640x480+100+200")    # 가로 * 세로 + x좌표 + y좌표

#윈도우 크기 변경
root.resizable(False, False) # x(너비), y(높이) 값 변경 허용

root.mainloop() 
  • 참고 링크
  • https://www.youtube.com/watch?v=bKPIcoou9N8&t=3723s

pyautogui 라이브러리 사용중 pyautogui.locateOnScreen이 정상동작하지 않을 경우에 대처하는 방법

pyautogui 라이브러리 사용중 pyautogui.locateOnScreen이 정상동작하지 않을 경우에 대처하는 방법.

윈도우 사용자라면 이와 같은 경험은 없을것으로 본다.
하지만 맥 사용자가 화면을 캡쳐해서 사용하려다 보면, 같은 이미지인데 찾을수 없는 현상이 생기곤 한다.

아래 테스트1, 테스트2와 같은 경우이다.
하루 정도 고민을 하며, 집에 돌아오자마자 해보면서 원인을 찾았다.

import pyautogui

# 테스트 1
num7 = pyautogui.locateOnScreen('test.png')
print(num7)

# 결과는 None

# 테스트 2

# 신뢰도를 좀 낮춰야 판단이 가능하다. 이유는? 캡쳐시 사이즈 변경??
img = pyautogui.locateOnScreen('./7.png', confidence=0.8, grayscale = True)
print(img)

나와 같은 고민을 한 맥 유저가 있으신가??
그렇다면 아래와 같은 명령어로 이미지를 캡처한다음에 실행 시켜보도록 하자.
정상으로 이미지를 찾아내는 마법을 볼것이다.

image = pyautogui.screenshot()
image.save('test.png')

원인은 무엇일까?
이미지 사이즈를 비교해보진 않았으나, 맥은 @2x 와 같은 이미지 프로세싱 기술을 사용할것으로 보인다.

귀찮아서 검증은 생략한다.

도움이 되었길.

맥에서 pip install error 발생시

파이썬 라이브러리를 설치 하려고 pip 명령어를 사용할것이다.
보통의 사용자들은 윈도우 사용자가 많기 때문에 pip install xxxx를 실행시키라고 할테니까 말이다..

맥에서 pip install xxxx 를 실행하면 아래와 같은 에러가 발생할 것이다.

pip install selenium  
zsh: command not found: pip

맥에서는 pip3를 사용할수 있다.

ip3 install paperclip
Collecting paperclip
  Downloading https://files.pythonhosted.org/packages/6f/6c/e7aade34b79c54034c689f2b5b5ae20f7ac974d28e63f54c06f32e6ca541/paperclip-2.2.4.tar.gz (65kB)
     |████████████████████████████████| 71kB 193kB/s 
Collecting Django (from paperclip)
  Downloading https://files.pythonhosted.org/packages/a9/4f/8a247eee2958529a6a805d38fbacd9764fd566462fa0016aa2a2947ab2a6/Django-3.0.5-py3-none-any.whl (7.5MB)
     |████████████████████████████████| 7.5MB 473kB/s 
중략...

pip을 설치해서 사용할수도 있는데, 굳이…

도움이 되길 바란다.