ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • django ch1 - ch4
    백엔드 2023. 3. 22. 23:26

    개념

    HTTP란 컴퓨터들끼리 HTML파일을 주고받을 수 있도록 하는 소통방식 또는 약속(protocol)이다.

    클라이언트는 서버에게 request를 보내고, 서버는 response를 클라이언트에게 보낸다.

     


     

    프로젝트 생성 및 환경 설정

    레포지토리를 fork한 후, cmd를 켜 get clone [레포지토리 주소]로 폴더를 생성해준다.

    pycharm에서 해당 폴더를 열고 터미널에 git checkout -b [브랜치 이름]를 쳐 branch를 만든다. (오른쪽 하단에서 현재 브랜치 확인 가능)

    해당 프로젝트를 위한 가상환경을 세팅해준다.

    Pycharm 상단 메뉴바 File - Settings - Project - Project Interpreter

    add interpreter을 눌러서 하면 된다. 이때 파이썬 버전 10은 mySQL과 연동이 안되니, 버전을 9로 낮춰서 해야한다.

    JW디렉토리에서 터미널에

    ./venv/Scripts/activate

    를 쳐 가상환경을 돌려준다.

    터미널에서 (venv)라는 명령어가 뜬다면 가상환경 설정에 성공한 것이다.

     

    그러나 윈도우 설정상 권한 에러가 발생한다. 

     


    venv/Scripts/activate : 이 시스템에서 스크립트를 실행할 수 없으므로 ....\PythonWorkspace\test-venv\Scripts\Activate.ps1 파일을 로드할 수 없습니다. 자세한 내용은 about_Execution_Policies(https://go.microsoft.com/fwlink/?LinkID=135170)를 참조하십시오.


     

    일회성 해결방안으로 (pycharm을 킬때마다 쳐야한다.)

    Set-ExecutionPolicy Unrestricted -Scope Process

    를 쳐봤지만 해결이 되지 않았다.

     

    Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

    로 권한에러를 해결했다.

     

    이제 보안상 깃허브에 올라가면 안되는 폴더 및 파일(venv/ 와 .idea/)을 .gitignore에 추가해준다.

    이는 멘토분께서 다 해두셨다.

     

    장고 버전을

    pip install django==3.2.16

    으로 깔아준다.


     

    개발 서버

    JW 디렉토리에서 터미널에

    django-admin startproject mysite

    를 치면 

    mysite/
        manage.py
        mysite/
            __init__.py
            settings.py #현재 장고 프로젝트의 환경 설정
            urls.py #URL 선언을 저장
            asgi.py #배포
            wsgi.py #배포

    가 생성된다. 

     

    mysite 디렉토리로 이동(CD)하여

    python manage.py runserver

    를 치면 개발 서버가 시작된다. 이제 본인의 웹 브라우져에서 http://127.0.0.1:8000/ 을 통해 접속할 수 있다.

     

    이때, 윈도우가 8000포트를 연결하지 못한다면

    python manage.py runserver 8080

    로 포트넘버를 바꿔 연결한다.

     

    앱을 모아둔 것이 프로젝트이다.

    앱을 생성하기 위해 manage.py가 존재하는 디렉토리에서

    python manage.py startapp polls

     를 치면

    polls/
        __init__.py
        admin.py
        apps.py
        migrations/
            __init__.py
        models.py
        tests.py
        views.py

    가 생성된다. 이제 설문조사 어플리케이션(앱)을 만들 수 있다.

     


     

    뷰 작성

    《polls/view.py》는 controller의 역할을 한다. 뷰를 호출하기 위해서는 해당 뷰와 연결된 URL이 필요하다.

    이때 URLconf가 사용된다. 이를 위해 urls.py라는 파일을 생성한다.

     

    urlpatterns = [
        path('', views.index, name='index'), #''시, index뷰로 보낸다.
        path('polls/', include('polls.urls')),
        path('admin/', admin.site.urls), #include()를 사용하지 않는 유일한 예외
    ]

    polls/5/result가 들어오면 include()함수는 5/result를 'polls.urls'로 보낸다. (하위 url)

    이제 index 뷰가 URLconf에 연결되었다. 

     

    path() 함수에는 2개의 필수 인수인 route와 view, 2개의 선택 인수인 kwargs와 name이 전달될 수 있다.

    - route 는 URL 패턴을 가진 문자열이다.

    - view는 경로로부터 특정한 view 함수를 호출한다.

    URL에 name을 지으면, 템플릿을 포함한 Django 어디에서나 명확하게 참조할 수 있다.

     


     

    데이터베이스 설치

     mysite/settings.py 파일을 열면 Django 설정을 모듈 변수로 표현한 모듈이 있다.

    기본적으로 SQLite를 제공하지만 mySQL로 변경해 진행했다.

    pip install mysqlclient

    를 깔아주고,

    해당 mySQL 폴더에서

    CREATE DATABASE jiwon;

    을 써 데이터베이스를 설정해 준 후,  mysite/settings.py에

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql', #기본설정
            'NAME': 'jiwon', #데이터베이스 이름
            'USER': 'root', #설정한 이름
            'PASSWORD': '',  #mySQL 비밀번호
            'HOST': 'localhost',   
            'PORT': '3306', #포트번호
        }
    }

    데이터베이스 속성값을 수정해준다. 그리고 gitignore 파일에

    /JW/mysite/mysite/settings.py

    를 추가한다. 이로써 보안까지 신경써서 작업할 수 있게 되었다.

     

    + 나중엔, .env파일로 뽑아내 import하는 식으로 구현했다.

    (작년에 프로젝트할 때, 다른 팀 백엔드에서 준 인가코드(?)를 프론트가 받아 깃허브에 올렸다가 해킹당해 30만원 가량을 물어준 적이 있다. 그래서 gitignore파일은 항상 신경써야 한다.)

     

    그 후, 

    python manage.py migrate
    python manage.py runserver

    가 잘 돌아간다면 Django와 mySQL 연동에 성공한 것이다.

     

    물론, 나는 에러가 났다.

    JW라는 경로에서 실행했기 때문이다.  CD mysite로 들어가 다시 실행해보니

     

    또 에러가 났다.

    해당 데이터베이스가 없다고 나온다. 그래서 JW 데이터베이스를 지우고 소문자 jiwon 데이터베이스로 다시 생성하니 잘 돌아간다.

     


     

    모델 생성

    모델이란 데이터베이스의 구조를 말한다. 이 투표 앱에서는 Question  Choice 라는 두가지 모델을 클래스로 만든다.

    Question 모델은 질문과 출판 날짜를, Choice 모델은 선택 텍스트와 투표 집계라는 필드(컬럼=열)를 가진다.

     

    polls/models.py에

    from django.db import models
    
    
    class Question(models.Model):
        question_text = models.CharField(max_length=200)
        pub_date = models.DateTimeField('date published')
    
    
    class Choice(models.Model):
        question = models.ForeignKey(Question, on_delete=models.CASCADE)
        choice_text = models.CharField(max_length=200) #글자수 200제한
        votes = models.IntegerField(default=0) #기본값 0으로 설정

    를 써준다. 여기서 models. 뒤에 붙는 CharField나 DateTimeField는 각 필드가 어떤 자료형을 가지는지 알려준다.

    cf. CharField는  max_length를 필수로 입력해줘야 한다.

    Foreignkey(외래키)는 각각의 Choice가 Question에 관계된다는 것을 알려준다.

     

    key 설정

     


     

    모델(스키마)의 활성화

    우리는 모델을 이용해

    • 데이터베이스 스키마를 생성
    • Question Choice 객체에 접근하기 위한 Python 데이터베이스 접근 API를 생성

    할 수 있다. 즉, 속성 및 속성값을 mySQL에 들어가 작업하지 않아도 된다는 뜻이다.

     

    그 전에 프로젝트에게 polls 앱이 설치되어 있음을 알려야한다.

    mysite/setting.py에

    INSTALLED_APPS = [
        'polls.apps.PollsConfig',
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    ]

    를 써주면 된다.

     

    python manage.py makemigrations polls

    이 코드를 통해 모델 클래스의 수정 및 생성을 mySQL의 jiwon DB에 적용했다.

    모델(models.py)을 수정했다면 장고에게 makemigrations를 통해 알려주고 migrate로 데이터베이스에 반영해야 한다.

    • makemigrations: models.py에서 적용한 변경사항이나 추가된 혹은 삭제된 사항들을 감지하여 파일로 생성 => 장고에서 파일만 생성
    • migrate: 적용되지 않은 migrations들을(설정값들을) 적용시키는 역할 => mySQL까지 적용

     

     

    python manage.py sqlmigrate polls 0001

    를 치면, 

    BEGIN;
    --
    -- Create model Question
    --
    CREATE TABLE "polls_question" (
        "id" serial NOT NULL PRIMARY KEY, #기본키로 설정
        "question_text" varchar(200) NOT NULL,
        "pub_date" timestamp with time zone NOT NULL
    );
    --
    -- Create model Choice
    --
    CREATE TABLE "polls_choice" (
        "id" serial NOT NULL PRIMARY KEY,
        "choice_text" varchar(200) NOT NULL,
        "votes" integer NOT NULL,
        "question_id" integer NOT NULL
    );
    ALTER TABLE "polls_choice"
      ADD CONSTRAINT "polls_choice_question_id_c5b4b260_fk_polls_question_id"
        FOREIGN KEY ("question_id")
        REFERENCES "polls_question" ("id")
        DEFERRABLE INITIALLY DEFERRED;
    CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");
    
    COMMIT;

    sqlmigrate 명령어로 금방 저장한 polls라는 migration이 어떤 SQL을 실행하는지 확인할 수 있다.

     

     

    기본키랑 외래키를 설정한 적은 없는데, sqlmigrate는 자동으로 생성해주는 것인지?


     

    python manage.py migrate

    를 쳐,

    아직 적용되지 않은 마이그레이션을 실제 데이터베이스에 적용해준다.

     


     

    데이터베이스 API

    필드에 속성값을 넣는 과정으로

    python manage.py shell

    를 통해 우선 Python shell을 실행시켜야 한다.

     

    >>> from polls.models import Choice, Question
    >>> Question.objects.all()
    
    >>> from django.utils import timezone
    >>> q = Question(question_text="What's new?", pub_date=timezone.now())
    >>> q.save()
    >>> q.id #1
    >>> q.question_text #"What's new?"
    >>> q.pub_date
    >>> q.question_text = "What's up?"
    >>> q.save()
    >>> Question.objects.all() #<QuerySet [<Question: Question object (1)>]>

    이렇게 객체를 생성하면 된다. (모델은 클래스이다.)

    그러나, 마지막 줄에

    <QuerySet [<Question: Question object (1)>]>

    는 객체를 보는데 전혀 도움이 되지 않기 때문에,

     

    polls/model.py에

    from django.db import models
    
    class Question(models.Model):
        # ...
        def __str__(self):
            return self.question_text
    
    class Choice(models.Model):
        # ...
        def __str__(self):
            return self.choice_text

    __str__()을 추가해준다.

     

    >>> from polls.models import Choice, Question
    >>> Question.objects.all() #<QuerySet [<Question: What's up?>]>
    >>> Question.objects.filter(id=1) #<QuerySet [<Question: What's up?>]>
    >>> Question.objects.filter(question_text__startswith='What') #<QuerySet [<Question: What's up?>]>
    
    >>> from django.utils import timezone
    >>> current_year = timezone.now().year
    >>> Question.objects.get(pub_date__year=current_year)
    >>> Question.objects.get(id=2) #DoesNotExist: Question matching query does not exist.
    
    >>> Question.objects.get(pk=1) #<Question: What's up?> id를 pk로 설정해두었다.
    ...
    
    >>> q.choice_set.create(choice_text='Not much', votes=0) #<Choice: Not much>
    >>> q.choice_set.create(choice_text='The sky', votes=0) #<Choice: The sky>

    이제 what's up? 으로 잘 나온다. ORM

     


     

    뷰(controller) 추가

    스프링부트에는 뷰가 templete(html)이었지만, Django에서는 뷰가 controller이다. 

    그래서 각 뷰는 요청된 페이지의 내용이 담긴 HttpResponse 객체를 반환하거나, 혹은 Http404 같은 예외를 발생하게 해야한다. 프론트(클라이언트)와 백엔드 간의 관계를 간단히 살펴보면,

     


    1. 클라이언트로부터 HTTP request 요청을 받으면 URLconf를 이용하여 URL을 분석합니다.
    2. URL 분석 결과를 통해 해당 URL에 대한 처리를 담당할 View를 결정합니다.
    3. View는 자신의 로직을 실행하면서, 만일 데이터베이스 처리가 필요하면 Model을 통해 처리하고 그 결과를 반환받습니다.
    4. View는 자신의 로직 처리가 끝나면, Template을 사용하여 클라이언트에 전송할 HTML 파일을 생성합니다.
    5. View는 최종 결과로, HTML 파일을 클라이언트에게 보내 HTTP response 응답합니다.

    라고 할 수 있다.

     

     polls/views.py 

    def detail(request, question_id):
        return HttpResponse("You're looking at question %s." % question_id)
    
    def results(request, question_id):
        response = "You're looking at the results of question %s."
        return HttpResponse(response % question_id)
    
    def vote(request, question_id):
        return HttpResponse("You're voting on question %s." % question_id)

    로 뷰를 추가했다. 

    뷰도 생겼으니 polls.urls 를

    from django.urls import path
    
    from . import views
    
    urlpatterns = [
        # ex: /polls/
        path('', views.index, name='index'),
        # ex: /polls/5/
        path('<int:question_id>/', views.detail, name='detail'),
        # ex: /polls/5/results/
        path('<int:question_id>/results/', views.results, name='results'),
        # ex: /polls/5/vote/
        path('<int:question_id>/vote/', views.vote, name='vote'),
    ]

    로 고쳐, 뷰와 연결해준다. 

    브라우저에 /polls/34/를 입력하면 detail() 함수를 호출해 "You're looking at question 34"라는 문장을 출력한다.

     


     

    뷰 작성 심화

    뷰는 데이터베이스의 기록를 읽을 수도 있고 Django나 Python에서 서드파티로 제공되는 템플릿 시스템을 사용할 수 있다.

    (뷰는 PDF를 생성하거나, XML을 출력하거나, 실시간으로 ZIP 파일을 만들 수도 있다.)

     

    위 '뷰 추가'에서는 뷰에서 templete의 역할까지 다 하고 있다. 이제 이를 분리해보자.

    polls/templates/polls/index.html에

    {% if latest_question_list %}
        <ul>
        {% for question in latest_question_list %}
            <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
        {% endfor %}
        </ul>
    {% else %}
        <p>No polls are available.</p>
    {% endif %}

    를 쓰고, 

    polls/views.py를

    ### 심화1 ###
    
    from django.http import HttpResponse
    from django.template import loader
    
    from .models import Question
    
    
    def index(request): #여기서 request가 어떻게 연결되는 것인지?
        latest_question_list = Question.objects.order_by('-pub_date')[:5] #질문 개수
        template = loader.get_template('polls/index.html')
        context = {
            'latest_question_list': latest_question_list,
        }
        return HttpResponse(template.render(context, request))

    로 index 뷰를 수정했다.

    이제 URLconf가 index함수를 부르면, polls/index.html 템플릿에 context를 전달한다.

    request  HttpRequest 개체이다.

     

    여기서 request가 어떻게 연결되는 것인지? 프론트에서 준 거.

     

     

    템플릿에 context를 넣어 HttpResponse객체를 templete에 넘겨주는 구문은 흔하다.

    따라서 Django는 render()이라는 단축기능을 제공한다.

     

    ### 심화2 ###
    from django.shortcuts import render
    
    from .models import Question
    
    
    def index(request):
        latest_question_list = Question.objects.order_by('-pub_date')[:5]
        context = {'latest_question_list': latest_question_list}
        return render(request, 'polls/index.html', context)

     더 이상 loader HttpResponse를 쓰지 않는다. 

    render() 함수는 request 객체를 첫번째 인수로 받고, 템플릿 이름을 두번째 인수로 받으며, context 객체를 선택적으로 받는다.

     


     

    404 에러

    polls/views.py에

    from django.shortcuts import get_object_or_404, render
    
    from .models import Question
    # ...
    def detail(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        return render(request, 'polls/detail.html', {'question': question})

    를 작성한다. get_object_or_404() 함수는 Django 모델을 첫번째 인자로 받고, 몇개의 키워드 인수(pk)를 모델 관리자의 get() 함수에 넘긴다. 만약 객체가 존재하지 않을 경우(pk가 존재하지 않을 경우), Http404 예외가 발생한다.

     

     

    여기서 pk가 없다 == 객체가 없다로 봐도 되는지? 네


     

    템플릿 시스템 사용

    polls/detail.html은 

    <h1>{{ question.question_text }}</h1>
    <ul>
    {% for choice in question.choice_set.all %} #질문 개수 반복문
        <li>{{ choice.choice_text }}</li> #질문 리스트로 출력
    {% endfor %}
    </ul>

    으로 작성되어 있다.


     

    하드 코딩이 뭔지? url 고정시켜 두는 것

     


     

    URL의 이름공간

    해당 프로젝트는 polls라는 앱 하나만을 가지고 진행했다. 하지만 여러개의 앱이 올 수 있기에 이를 구분하기 위해

    URLconf에 namespace를 추가한다.

     

    polls/urls.py 를

    from django.urls import path
    
    from . import views
    
    app_name = 'polls'
    urlpatterns = [
        path('', views.index, name='index'),
        path('<int:question_id>/', views.detail, name='detail'),
        path('<int:question_id>/results/', views.results, name='results'),
        path('<int:question_id>/vote/', views.vote, name='vote'),
    ]

    로 수정한다. name이라는 인자를 달아줬다.

     

    이제, polls/index.html 템플릿의 기존 내용을

    <li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>

    로 네이밍을 명확히 해준다.

     


     

    Form

    polls/detail.html를 수정해 템플릿에 HTML <form> 요소를

    <form action="{% url 'polls:vote' question.id %}" method="post">
    {% csrf_token %}
    <fieldset>
        <legend><h1>{{ question.question_text }}</h1></legend>
        {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
        {% for choice in question.choice_set.all %}
            <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
            <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
        {% endfor %}
    </fieldset>
    <input type="submit" value="Vote">
    </form>

    로 추가해준다. 

    for문을 돌며 데이터베이스에 저장된 선택지의 개수를 라디오 버튼으로 표현한다. 각 라디오 버튼의 name은 choice이며 이 중 하나를 선택하면 form요소는 서버에 choice = #id 을 post한다.

     

    forloop.counter  for 태그가 반복한 횟수를 나타낸다.

    내부 URL을 대상으로 하는 모든 POST 양식은 템플릿 태그를 사용해야 한다.{% csrf_token %}

     

    polls/urls.py에

    path('<int:question_id>/vote/', views.vote, name='vote'),

    를 추가하고,

    polls/views.py에

    from django.http import HttpResponse, HttpResponseRedirect
    from django.shortcuts import get_object_or_404, render
    from django.urls import reverse
    
    from .models import Choice, Question
    # ...
    def vote(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        try:
            selected_choice = question.choice_set.get(pk=request.POST['choice'])
            #선택된 choice의 ID를 문자열로 반환해 변수에 넣는다.
            
            
        except (KeyError, Choice.DoesNotExist):
            #choice가 없다면, request.POST['choice'] 는 KeyError가 일어나며
            return render(request, 'polls/detail.html', {
                'question': question,
                'error_message': "You didn't select a choice.",
            })
            #에러메세지와 설문조사 폼을 다시 보여준다.
            
            
        else: #제대로 선택이 되었다면,
            selected_choice.votes += 1
            selected_choice.save()
            return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
            #reverse()함수는 해당 뷰를 하드코딩하지 않고 가리키게 한다.

    추가한다. 이제 어떤 이가 설문조사를 한 후에는 vote() 뷰는 설문조사 결과페이지로 리다이렉트한다.

     

    결과페이지를 만들어보자.

    polls/views.py에

    from django.shortcuts import get_object_or_404, render
    
    
    def results(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        return render(request, 'polls/results.html', {'question': question})

    를 추가하고,

    polls/results.html에

    <h1>{{ question.question_text }}</h1>
    
    <ul>
    {% for choice in question.choice_set.all %}
        <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
    {% endfor %}
    </ul>
    
    <a href="{% url 'polls:detail' question.id %}">Vote again?</a>

    를 추가한다. 

     


     

    제네릭 뷰 사용

    우리가 지금까지 작업했던 뷰는 URL에서 전달된 매개변수에 따라 데베에서 데이터를 가져오거나 템플릿을 로드하는 것이다. 이런 과정을 Django는 '제네릭 뷰'라는 시스템으로 지름길을 제공한다.

     

    이는 일반적인 패턴을 추상화하여 앱을 작성할 때 Python코드를 작성하지 않도록 돕는다.

    그러기 위해서는 3가지 단계가 필요하다.

    1. URLconf를 변환
    2. 불필요한 오래된보기 중 일부를 삭제
    3. Django의 제너릭 뷰를 기반으로 새로운 뷰를 도입

     

    git ignore

     

    [GIT] git 캐시 삭제

    GIT 캐시를 삭제해야하는 이유?? 우리가 프로젝트를 만들고 gitignore을 하지않고 git에 add, commit을 해버릴 경우가 있다. 그러면 일단 git 자체에 쓰여진 상태이기 때문에 gitignore가 먹히지 않는다. 캐

    gh402.tistory.com

    git ignore 파일 확인

    git status --ignored

     

    특정 개수만큼의 커밋 기록을 제거

     # 가장 최근의 커밋 기록을 1개 제거 (위와 동일)
      git reset --hard HEAD~1
      # 가장 최근의 커밋 기록을 2개 제거
      git reset --hard HEAD~2

     

    특정 커밋으로 복구

      git reset --hard <commit id>

     

     

    더 삽질한 건 밑에 정리해두었다^^

     

     

    [Git] 커밋 기록 삭제 및 복구

    CEOS 과제를 하던 중 데이터베이스 비밀번호가 적힌 파일을 gitingnore에 추가하지 않고 push 해버렸다. 첫 번째 시도(커밋 기록 삭제) 아래 사진처럼 .env(my_setting.py로 설정)을 따로 둔 뒤, settings.py에 i

    jwkdevelop.tistory.com


     

    Django REST Framework

    웹 API를 구축할 수 있는 툴킷으로, Model 을 바탕으로 조건에 맞는 API를 개발할 수 있다.

     

    pip install djangorestframework
    pip install django-filter #Filtering support

    mysite/settings.py을

    INSTALLED_APPS = [
       ...
        'product',
    		'rest_famework', #추가
    ]

    로 바꿔준다.

     

    Serializer는 queryset 과 model instance 같은 것들을 쉽게 JSON 또는 XML 의 데이터 형태로 렌더링 할 수 있게 해줍니다. 우리는 Product 모델을 serialize 해줘야 하기 때문에 ModelSerializer를 사용한다.


     

    참조) 

     

    Django

    The web framework for perfectionists with deadlines.

    docs.djangoproject.com

     

    Django - 기본적인 app 생성해 json 출력해 보기 (1)

    아아주 기본적인, 내가 데이터를 전송해 입력하고 입력해둔 데이터를 출력하는 앱에 대해 작성하려고 한다. 어느 정도는 django 튜토리얼과 겹칠 것이다.

    velog.io

     

    장고(Django) - 마이그레이션(Migration)

    마이그레이션(Migration)이란? 장고 공식 문서에서는 마이그레이션이 모델의 변경 내역을 DB *스키마에 적용시키는 장고의 방법이라고 설명하고 있습니다. 장고는 ORM을 사용하기 때문에 models.py와

    tibetsandfox.tistory.com

     

    django restful api 구현

    settings.pyrest_framework와 user(app이름)를 추가해준다.일단 database에 저장하고 가져다 쓸 데이터의 schema를 만들어야한다. 기본적으로 schema안에는 무조건 primary key가 있어야 하기 때문에 간단하게 id를

    velog.io

     

    [Python] django 모델을 이용한 데이터베이스 처리

    장고는 모델(Model)을 활용하여 데이터베이스를 처리합니다. sqlite 데이터베이스는 장고의 기본 데이터베이스입니다. 보통은 데이터베이스에 SQL 쿼리문을 이용하여 데이터를 조회하고 저장하고

    yjshin.tistory.com

     

Designed by Tistory.