24. TIL (CRUD2_주인과 강아지)

dream.log·2021년 7월 21일
1

TIL

목록 보기
22/42
post-thumbnail

CRUD의 과제를 수행하며 뼈저리게 깨달은 초기 셋팅의 중요성^^..
mysql 설정 오류가 나서 데이터베이스가 충돌됐고,
migrate 이후 그 사실을 알았다... 🤣

프로젝트를 다시 만드는 것이 효과적이라는 멘토님의 말씀에
결국 날려버렸다..
이러한 시행착오를 반복하지 말자고^^ 나를 위해. 다시 적어보는 포스팅.

1. 초기셋팅

기본 작업을 할 터미널, MYSQL 돌릴 터미널, Runserver 돌릴 터미널
총 3개를 열어준다.

☑️ 기본 터미널 셋팅

conda create -n owner python=3.8
conda activate owner
pip install django
pip install mysqlclient
pip install django-cors-headers
pip install PyMySQL

django-admin startproject owner

☑️ mysql 셋팅

mysql -u root -p
create database owner character set utf8mb4 collate utf8mb4_general_ci;

2.Django Setting

2-1. settings.py 파일 변경

✅ ALLOWED_HOST 설정,
✅ INSTALLED_APP,MIDDLE_WARE 주석처리
(SECRET_KEY미리 복사해주기)

❌~~ 한 번에 모든 셋팅을 완료해도 되는가?~~
: coreshead app 설정 등 settings.py 파일에서 수정해야 하는 설정들이 있어서 이 설정들을 한번에 해주면 안되는 것인지?에 대한 의문이 있었는데, 오류가 발생할 경우 어디서 문제인지 알 수 없기 때문에 웬만하면 하나씩!
수행해주는 것이 좋다!

1) ALLOWED_HOSTS = [ '*'cd ] : 모든 ip를 허용한다.
2) INSTALLED_APPS = admin, auth 주석처리,  'corsheaders' , 추가하기
MIDDLEWARE = csrf,auth 주석처리하기, 
'corsheaders.middleware.CorsMiddleware',
=> 이미 내장되어 있기 때문에

2-2. urls.py 파일 변경

from django.urls import path

urlpatterns = [
]

2-3. my_settings.py 파일 만들기

: manage.py 파일이 존재하는 디렉토리에서 만들어줘야 한다.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': '디렉토리명' (BASE_DIR / 'db.sqlite3'),
        'USER': 'root' ,
        'PASSWORD' : ' ' ,
        'HOST': '127.0.0.1',
        'PORT: '3306',
 
    }
}
SECRET_KEY = 'password~~~~'
  • user = 'root'
  • password = mysql password
  • secret_key = settings.py 파일에서 복붙.

2-4. settings.py 파일 수정(my_settings.py와 연동하기)
: m1의 경우 PyMySQL을 꼭!!!!!!!!!!!!!💯 설치해야 한다.
🌱 DATABASES, Secret_key 수정하기
🌱 PyMySQL 설정
🌱 Coreshead 관련 설정

상단에 작성해야 하는 코드와 중간에 작성해야 하는 코드가 함께 있으니
빼먹지 말고 잘 수정하도록 하자!

from pathlib        import Path 
#기존에 settings.py 에 있는 코드
from my_settings    import DATABASES, SECRET_KEY
import pymysql
...
INSTALLED_APPS = [
...
		'corsheaders'
]
MIDDLEWARE = [
	...
		'corsheaders.middleware.CorsMiddleware',
	...
]
DATABASES = DATABASES

SECRET_KEY = SECRET_KEY

pymysql.install_as_MySQLdb()

#REMOVE_APPEND_SLASH_WARNING
APPEND_SLASH = False

##CORS
CORS_ORIGIN_ALLOW_ALL=True
CORS_ALLOW_CREDENTIALS=True

CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
)

CORS_ALLOW_HEADERS = (
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
		#만약 허용해야할 추가적인 헤더키가 있다면?(사용자정의 키) 여기에 추가하면 됩니다.
)

2-5. 서버 구동해서 아무 문제가 없는지 체크체크!
python manage.py runserver
:manage.py 파일이 있는 곳에서 실행하여 계속 돌려준다~

3. git 연동하기

  • git init
  • .gitignore 생성하기
    • 추가할 키워드 :python, linux, VisualStudioCode,
      vim,macOS,pycharm
    • create 후 생성된 내용을 .gitignore 파일에 넣고 my_settings.py 파일도 아래에 넣어 git에 올라가지 않도록 관리해준다.
  • git add .
    : add + '파일명' 을 통해 필요한 파일만 add 하는 것도 가능하다
  • git commit -m "메시지"
  • git status : 중간 상태 체크
  • github repository 생성해주기
  • git branch -M main : branch Master -> Main으로 변경
  • git remote add origin [http://github.com/damdream/owner]
    : github repository에서 복사해오기
  • git checkout -b [브랜치이름]
    브랜치를 만들어준다!
  • git push origin [브랜치이름]

4. app 만들기

python manage.py startapp owners
: owners라는 이름의 앱 만들어주기
-> settings.py 로 이동하여 INSTALLED_APP에 'owners' 추가하기

5. Models.py 작성하기

from django.db import models

class Owner(models.Model):
    name = models.CharField(max_length=45)
    email = models.CharField(max_length=200)
    age = models.IntegerField(null=True)

    class Meta:
        db_table = 'owners'


class Dog(models.Model):
    owner = models.ForeignKey('Owner', on_delete=models.CASCADE)
    name = models.CharField(max_length=20)
    age = models.IntegerField(null=True)

    class Meta:
        db_table = 'dogs'

🌈 작성시 유의할 점

  • age null값은 true를 주지 않는 것이 좋다.
    나이를 입력하지 않을 수도 있다고 생각해 null=true 를 지정하였는데, 굳이 지정할 필요가 없는 옵션이었다.

  • models.Model => 내부 모듈을 이용하고, 장고 ORM을 사용한다는 것을 알려주기 위함.

  • charfield 뒤 Unique = True 적용해주면
    중복값이 생성되지 않고 1개만 만들어짐!

    name = models.CharField(max_length=45. Unique = True)
  • INT = Integerfield 사용하기.

  • age = PositiveInteger
    -가 없기 때문에 positive를 사용하는 것이 더 효율적이다!

  • app은 데이터 기준으로 구분하기 때문에 강아지와 주인의 app을 분리하는 것이 좋다. 나는 하나로 구현...!

6. Makemigrations - migrate 진행하기

python manage.py makemigrations
python manage.py migrate
  • models.py => makemigration => migrate => db확인 => view 작성 => url 맵핑 => httpie

httpie 할 때 서버 하나 꼭 켜놓고 진행하기!

7. Views.py 작성하기

: Models.py에서 작성한 내용이 연결되어 출력될 수 있도록 작성한다.
status도 꼭 적어주어야 하며, try - except 구문을 활용해 실행이 되지 않았을 경우를 따로 분리하여 작성해준다.
어떠한 목적으로 코드를 작성하는지 생각하며 Input - Output 을 고려하자.

#import 목록
import json

from django.http import JsonResponse
from django.views import View
from owners.models import Owner, Dog

# Class 구현해내기
class OwnerListView(View):
    def post(self,request):
        data = json.loads(request.body)
        try:
            name = data['name']
            email = data['email']
            age = data['age']
            Owner.objects.create(name=name, email=email, age = age)
            
        except KeyError:
            return JsonResponse ({'MESSAGE':'IVALID_KEY'}, status=400)
        return JsonResponse({'MESSAGE':'SUCCESS'}, status=201)

    def get(self,requset):
        owners = Owner.objects.all()
        results = []

        for owner in owners :
            dogs = [
            
                {"이름":dog.name} for dog in Dog.objects.filter(owner_id=owner.id)
            ]
            results.append(
                {
                    "name": owner.name,
                    "email" : owner.email,
                    "dog_list": dogs
                }
            )
            return JsonResponse({'result': results}, status =200)


class DogListView(View):
    def post(self,request):
        try:
            data = json.loads(request.body)
            name = data['name']
            owner = Owner.objects.get(name=data['owner'])
            age = data['age']
            dog = Dog.objects.create(age=age,name = name, owner = owner)
        except KeyError:
            return JsonResponse ({'MESSAGE':'IVALID_KEY'}, status=400)
        return JsonResponse({'MESSAGE':'SUCCESS'}, status=201)

    def get(self,request):
        dogs=Dog.objects.all()
        results = []
        for dog in dogs:
            results.append(
                {
                    'owner': dog.owner.name,
                    'name': dog.name,
                    'age': dog.age
                }
            )
        return JsonResponse({'MESSAGE':results}, status = 200)    

🌈 작성 시 유의점

  • from ~ render :
    http 파일 만들 때 받아오는 파일이므로 지금은 지우면 된다.
  • from django.views import View
  • 코드 작성 시, Input과 Output을 고려하자!
    오너의 정보를 클라이언트로부터 받아서 데이터베이스에 저장하는 기능 구현이 목적인 코드.

    • input
      : 데이터 측면 (name,age,email),
      http request의 측면 (post,Json 형식으로 body에 담김)
    • output : result, server(status)
    • 목적 : 클라이언트로부터 http post 요청으로 http request message body에 owner의 정보를 JSON 형태로 받아 데이터베이스 오너스테이블에 저장하는 기능 구현.
    • 데이터베이스 어디에 저장하는가? 데이터 베이스 owners table에 저장.
  • handler method = post, get 등등등

  • def post(self,request)
    : 클라이언트로부터 http post 요청으로-
    json data이니 딕셔너리 형태로 감싸서 보내주어야 한다.
    data = json.loads (request.body)
    => 파이썬에서 읽을 수 있게 하기 위해서 native data type으로 바꿔줌

    INPUT : { name: "", age: "" , email: ""} 정보 담기
    OUTPUT : {message: success}

  • 데이터 베이스 owners table에 저장을 코드로 작성하면?

    Owner.objects.create (name = data["name"], email =data[ "email"], age =.data["age"]) 
  • response 필요

from django.http import JsonResponse

모범 views.py

import json
from django.http import JsonResponse
from django.vews import view
from .models import Dog
from .owner.models import Owner

class Dogview(View)
  def post(self,request):
  data = json.loads(request.body)
  if not Owner.objects.filter(id=data["owner_id"]).exists():
	return JsonResponse({"message" : "OWNER_DOES_NOT_EXISTS"}, status = 404}) : 
	존재하지 않아서 에러 리턴해주기
  Dog.objects.create(
	name = data["name"],
	age =  data["age"],
	owner_id = data ["owner_id"]
)
 return JsonResponse ({"message" : "sucess"}, statuse = 201)

8. Urls.py 작성하기

  • 최상위 url은 app과 연결되며 app 안의 url은 view와 연결된다.
  • 부모 urls.py는 server로 오는 요청 경로 처리하는 파일.
  • include : app을 사용하겠다는 요청이 오면 다시 상세 app으로 보내주는 역할. 연결을 해주는 역할이다.

* Owner Urls.py

from django.urls import path, include

urlpatterns = [
    path('owners', include('owners.urls'))
]

* Owners Urls.py
(파일이 없으니 별도로 만들어주어야 한다!)

from django.urls import path
from owners.views import OwnerListView, DogListView

urlpatterns = [
    path('/owners', OwnerListView.as_view()),
    path('/dogs',DogListView.as_view()),
]

9. httpie Post - Get 실행하기

post로 views.py에 작성한 양식에 맞추어 작성해 데이터를 만든다.

http -v POST
127.0.0.1:8000/owners/owners name="담이" email="dam@gmail.com", age="21"
  • Owners app에 owners이므로 맞추어 입력하고, 중간에 쉼표나 공백이 들어가지 않도록 유의한다. 들어가면.. post가 실행되지 않는다^^

  • Owners 정보를 입력한 후, 강아지 정보도 입력해주기!

http -v POST 127.0.0.1:8000/owners/dogs  age=3 name="까미" owner="담이"

10. MySQL에서 입력한 데이터 확인하기

database Create 해 놓은 상태에서 입력할 명령어들이다.

SHOW databases; 데이터베이스를 보여줘!
Use Owners; 사용하려는 데이터베이스명으로 변경
SHOW tables; 테이블을 보여줘!
select * from Owners; owners의 데이터를 보겠다
select * from dogs; dogs의 데이터를 보겠다

⭐️ 완성 데이터 ⭐️



👩🏻‍💻 기억하고 싶은 개념들

✔️ 데이터를 잘못 입력해 shell을 열어서 수정해야한다면?
from owners.models import * 하여
내가 수정해야하는 내용을 import해서 불러와야 수정이 가능하다!

🐶 강아지가 중복으로 생겨 수정을 한 흔적들..

: database는 민감하니 delete는 최소한으로 사용하고, 데이터를 수정해주자.
(수정하다보니 강아지를 7마리나 만들어버렸다. 하하)

✔️ Post가 되지 않아 강제로 Owners를 하기 위해서는?

INSERT INTO owners (name, email, age) VALUES("도담", "do@gmail.com", "20")

MYSQL 상에서 입력하는 데이터이다. MySQL의 명령어는 대문자로!


Post error와 database 에러를 겪으며 멘토님들과 많은 동기들,
선배 블로거 분들의 도움을 받으며 과제를 완성했다.
다시 개념을 잘 정리하며, 이해하여 내 것으로 만들고 내일부터 시작하는
Westagram session도 잘 진행해보자! 아자!

profile
한 걸음, 한 걸음 포기하지 않고 발전하는 Backend-developer 👩🏻‍💻 노션 페이지를 통한 취업 준비 기록과 회고를 진행하고 있습니다. 계획과 기록의 힘을 믿고, 실천하고자 합니다.

0개의 댓글