-------------------------------------------------------------------------------------------------------------


[ django(장고) 실습 : Django 기초 지식, 프로젝트 생성 ~ 앱 생성 및 구성 ]


< Django-setup ; 리눅스 ubuntu 환경>


* 터미널에서 python3 실행시 quit : ctrl + z

* 터미널 관리자 계정 패스워드 설정 : sudo passwd root

* 터미널 관리자 계정 진입 : su

* 파이썬 2.0대 버젼의 라이브러리 인스톨 모듈 pip 설치 : apt-get install python-pip 

(이 모듈로 장고를 설치하면 장고 초기버젼이 설치됨.)

* 파이썬 3.0대 버젼의 라이브러리 인스톨 모듈 pip 설치 : apt-get install python3-pip 

* 장고를 설치할 pip 버젼이 최신 버젼인지 확인 : python3 -m pip install --upgrade pip

* 장고 설치 : pip3 install django or python3 -m pip install django

* 파이썬에 진입해서 장고 버젼 확인 : import django --> django.__version__

* 장고 서버 구동 : 해당 프로젝트 폴더 위치로 진입 --> python3 manage.py runserver (127.0.0.1:8000 생략 가능) --> 브라우져에 127.0.0.1:8000 입력하여 장고 기본 화면 확인

(타PC 접속 : python3 manage.py runserver 192.168.0.10:8000 --> 

장고 해당 프로젝트 폴더의 settings.py 의 allowed host 에 192.168.0.10 추가 후 접속)

* 장고 runserver 2회 실행시 'That port is already in use' 오류 해결

 - Ctrl+C : 서버 구동창에서 단순히 빠져나옴. port는 백그라운드에서 점유 당하고 있으나 hosting은 안 되는 상태.

 - sudo fuser -k 8000/tcp --> This should kill all the processes associated with port 8000.

 - PID 알아내기 : ps auxw | grep runserver


-------------------------------------------------------------------------------------------------------------


< Django-Project 생성, Project 하위에 앱 생성 >


 - 예시 환경 : 작업공간 = testNetwork 만들기 

( 터미널에서 cd / 로 최상위 디렉토리 진입 --> mkdir testNetwork)

 - 장고 프로젝트(project1) 생성 : testNetwork 진입 --> django-admin startproject project1

   ; project1 폴더가 상위, 하위 2개 만들어짐. 상위 폴더는 작업공간이며, 하위 폴더가 살제 프로젝트 폴더임.

   ; 장고앱은 상위 폴더 바로 아래에 만들어져야 함.(실제 프로젝트 폴더의 위치와 같은 레벨에 앱폴더 생성)

 - 장고 앱(dapp1) 생성 : poject1 진입 --> django-admin startapp dapp1


-------------------------------------------------------------------------------------------------------------


< Django-작동 기본 원리 및 초기 작업 >


* 작동 원리(project1 단독 작동시) : 클라이언트가 특정 url 로 접속 --> project1/settings.py 의 ROOT_URLCONF 에 등록된 project1/urls.py 파일내 urlpatterns-path의 첫번째 인수를 이용하여 사용자가 입력한 URL의 서버주소를 제외한 뒷 부분의 url 패턴을 검사 --> 일치하는 path의 두번째 인수에 입력된 'view.py 내의 함수' 의 HttpResponse가 작동하여 webpage 내용을 html 형태로 화면에 출력함.

* 작동 원리(dapp1 연동 작동시) : project1/settins.py 의 INSTALLED_APPS 에 dapp1 을 등록(dapp1 이 project1의 앱이라는 것을 장고에게 인식 시킴) --> project1/urls.py-urlpatterns-path 의 두번째 인수로 view.py의 함수명이 아닌 include('dapp1.urls')를 넣어줌 --> dapp1/urls.py 과 dapp1/views.py 를 생성(dapp1내의 urls.py-urlpatterns-path는 사용자가 최초 입력한 url의 끝에 웹페이지 별로 새로 생성된 문자를 읽어서 일치하는 pattern의 dapp1/view.py의 함수로 보냄.(즉, 메인 웹페이지내에서 선택 조건에 따라 다른 웹페이지 열람 가능)

* 도움말 보기: 프로젝트 폴더에서 python3 manage.py help


-------------------------------------------------------------------------------------------------------------


< 네트워크 설정 2차 >


* 서버pc와 클라이언트pc의 인터넷사용 어댑터는 

 - '사용 가능하면 자동으로 이 네트워크에 연결' --> 체크 확인

 - '모든 사용자가 네트워크에 연결 가능' --> 체크 해제

* 내부망 어댑터는 

 - '사용 가능하면 자동으로 이 네트워크에 연결' --> 체크 확인

 - '모든 사용자가 네트워크에 연결 가능' --> 체크 해제

* 어댑터 4개의 identity-name을 모두 적절한 영문명으로 수정

* 어댑터 설정 변경 확인 : route -n 입력 --> 인터넷망은 Metric이 100, 내무망은 Metric이 101 확인.


-------------------------------------------------------------------------------------------------------------


< Django-template 기초 >


* 작동 원리(template 파일 사용) : dapp1/views.py 의 httpResponse('string') 대신 render(request, 'dapp1/index.html') 함수를 사용 --> dapp1/templates/dapp1/index.html 파일을 만들어주면 views.py-render 함수가 index.html 파일을 rendering해서 화면에 보여줌.

* render 함수는 project1-dapp1 내에 사용자가 만든 templates 폴더를 기준으로 하위 폴더를 검색함

--> 즉, templates 폴더 하위에 바로 index.html 등을 만들어주면, 다른 앱에 동일 이름의 index.html 파일이 존재할 경우 에러가 발생할 수 있음. 따라서 통상적으로 dapp1/templates 폴더 하위에 다시 dapp1 폴더를 만들어서 그 아래에 templte html 파일을 저장함 ;  render(request, 'dapp1/index.html')

* 작동원리(layout 파일 사용 ; 컨텐츠를 포함하는 다수의 html 파일과 1개의 layout.html 파일을 연동 ; 즉, 동일한 layout 에 내용만 바꿔 넣을 수 있음.) : extends 와 block 문을 사용하여 layout으로 확장

 - laout.html 에 html 기본 골격을 작성하고 body tag 안에 {% block title %}{% endblock %}

 - 컨텐츠 파일인 index.html 내용에는 

{% extends "dapp1/layout.html" %}

{% block title %} contents ~~~~ {% endblock %}

 - index2.html 파일을 만들어서 동일한 layout.html 로 확장 사용 가능.

 - layout의 head tag내에 nav tag로 w3school의 css navigation bar css - lsit와 style code를 넣어주고, body tag에 block~endblock 을 사용하고, 다양한 내용 html 페이지에서 layout으로 확장하면, 리스트는 유지되면서 리스트 항목을 누를때마다 안쪽의 내용만 바뀌는 웹페이지를 구현 가능함.


-------------------------------------------------------------------------------------------------------------


< Django-ORM 기초 >


* ORM : Object-Relationnal Mapping (장고에서 만들어진 객체를 DB 데이타에 맵핑하여 저장해주는 기능)

* django 앱에서 models.py 파일에 DB 형태를 정의해주면 장고가 알아서 DB와 table을 생성함.

* 모델정의(DB만들기) : models 모듈의 Model 클래스를 상속받는 테이블 클래스를 정의 --> field 값(변수===컬럼명)으로 models 모듈의 attribute(데이터 특성; 문자,숫자,날짜 등) 를 정의하여 할당.

ex)

class Person(models.Model):

    first_name = models.CharField(max_length=30)

    last_name = models.CharField(max_length=30)

* table 명은 기본적으로 'app이름_class명'으로 장고가 자동으로 명명함.(사용자가 오버라이드 가능)

* id field 는 기본적으로 장고가 자동으로 생성함.(사용자가 오버라이드 가능)

* 장고의 model == DB, class == table, field(class attribute) == column, instance == record

* 장고는 sqlite db를 기본으로 탑재하고 있으나, 실 사이트 배포시는 MYsql, PostgreSQL, MongoDB 등과 연동해야 함.

* primary_key(pk) : 일반적으로 장고가 자동으로 생성하는 id field를 의미함.

ex) 자동생성 

id = models.AutoField(primary_key=True)

ex) 수동지정

class Fruit(models.Model): 

    name = models.CharField(max_length=100, primary_key=True)

If True, this field is the primary key for the model.

If you don’t specify primary_key=True for any fields in your model, Django will automatically add an IntegerField to hold the primary key, so you don’t need to set primary_key=True on any of your fields unless you want to override the default primary-key behavior. The primary key field is read-only. If you change the value of the primary key on an existing object and then save it, a new object will be created alongside the old one.

from django.db import models

* foreign key : 외래키, data와 data 간의 관계를 맺어주는 키 (ex: 설문 항목1과 항목1의 예시 1~4간의 관계)

* 마이그레이션 실행을 위한 마이그레이션 파일 생성 (ORM 1단계) : project1 폴더에서 python3 manage.py makemigrations (python3 명령어를 찾을 수 없다는 오류나오면 리눅스 updrage 후 터미널 재실행)

--> 명령실행하면 dapp1 밑에 0001_initial.py 파일이 만들어지며(?) 그 안에 DB 업데이트 내용이 마이그레이션 class로 만들어짐.

* 마이그레이션 실행 (ORM 2단계) : python3 manage.py migrate --> project1 하위의 db.sqlite3 파일에 데이타가 저장됨.

* 저장된 데이타는 GUI 환경의 장고 admin 페이지를 제공하며, admin page에서 저장된 db 데이타를 확인 가능함. admin page를 사용하려면 장고 admin 계정을 생성해야 함 ; python3 manage.py createsuperuser --> 192.168.0.10:8000/admin

* 기본 설정의 admin page에서는 user, group 만 보이고, db 데이타는 안보임.

 - dapp1/admin.py 에 생성한 db 모델을 등록해줘야 admin page가 Model class(table)를 인식함. (admin page에 해당 table이 보이지만 field 등록은 안 되었기 때문에 각 record의 값이 구분되어 보이지 않고, Model class명 1,2 의 형태로만 표시됨.

ex)

from django.contrib import admin

from myproject.myapp.models import Author


class AuthorAdmin(admin.ModelAdmin):

    pass

admin.site.register(Author, AuthorAdmin)

 - modesl.py의 Model class(table)가 등록된 code의 하단에 __str__ 구문으로 field값(column) 각각을 변수로 return 해주면, admin 페이지에서 각 recode가 구분된 값으로 표시됨.

ex)

    def __str__(self):

        return '%s %s' % (self.first_name, self.last_name)


-------------------------------------------------------------------------------------------------------------


< Django-template 활용 >


* URL string 받아오기(URL의 id값 등을 받아서 변수로 저장하여 사용 가능)

 - urls.py 에 urlpatterns 정의 : path('test.html/<int:year>, test),

 - view.py 에 *args와 **kwargs 를 인자로 넘겨받는 test 함수 정의하여 사용

def test(request, *args, **kwargs):

result = kwargs['year']

return HttpResponse(result)

* view.py 에 함수 대신 django의 View classs를 상속하는 Test2 class 정의하여 사용.

(class 내에 여러개의 함수를 구현하여 사용 가능하다고 했으나 확인되지는 않음 확인 과정에서는 첫번째 함수만 실행되고 종료됨.)

 - urls.py 에 urlpatterns 정의 : path('test2.html/<int:year>, Test2.as_view()),

 - view.py 에 View classs를 상속하는 Test2 class 정의

 - Test2 class에 *args와 **kwargs 를 인자로 넘겨받는 get 함수를 정의하여 사용

def get(self, request, *args, **kwargs):

result = kwargs['year']

return HttpResponse(result)

 - classs를 내부 함수에 POST, GET 함수를 사용하여 data를 주고 받을 수 있다고 함.(추가 학습 필요)

* views.py 의 값 또는 변수를 dictionary 형태로 context 변수에 저장해서 render 함수의 세번째 인자로 입력해서 그 data를 html template 파일에 넘겨서 사용할 수 있다.(이를 이용하면 URL string으로 view 함수가 받을 값을 템플릿에 넘겨주어 사용 가능할 듯.)

 - view.py의 함수에서 context를 넘겨주는 render 코드

def news(request):

news_contents = ['aaa','bbb','ccc','ddd']

contents_dict = {'Person' : new_contents}

return render(request, 'dapp1/news,html', context = contents_dict)

 - 템플릿에서 Peson을 리스트 data 로서 받아서 사용하는 코드

{% block bldy %}

{% for person in Person %}

{% if person == "bbb" %}

{{person}}

{% endif %}

{% endfor %}

{% endblock %}

* templates 폴더를 프로젝트 폴더 바로 밑으로 옮기기

 - project1 밑에 templates 폴더 생성 --> templates 폴더 밑에 dapp1 폴더 생성

 - settins.py 의 BASE_DIR 바로 밑에 TEMPLATES_DIR = BASE_DIR + "/templates" 정의

 - settings.py 의 TEMPLATES-'DIRS' : [TEMPLATES_DIR]


-------------------------------------------------------------------------------------------------------------


< Django-ORM 활용 >


* Django Shell 사용, Queryset class, DB에 data 저장, 조회, 수정

 - 장고 명령어 도움말 보기 : python3 manage.py --help --> 목록에 shell 보임

 - 장고 shell 실행 : python3 manage.py shell

 - DB-table에 데이타 저장(DB record는 class의 instance임)

from dapp1.models import Person

p=Person(first_name = "철수", last_name = "김")

p.save

 - 추가한 record의 다른 field 값 수정하기

p.age = 17

p.save

p.delete(삭제) --> 완전 삭제는 아니고 shell에서는 잠시 살아있으므로 p.save로 다시 살아남.

 - 원하는 data 조회(queryset을 만들어서 사용; 쿼리셋에 for 문 적용 가능)

Person.objects ; queryset 생성 기능을 포함하는 DB manager class

temp = Person.objects.all() ; Person class 전체 data를 조회하는 쿼리셋

 - filter와 fieldlookups 사용하면 대부분 DB data 제어 가능.

temp.filter(last_name="김")

temp.filter(age__lt ="10")

temp.filter(age__gt ="10")

 - 쿼리셋이 아닌 1개의 데이터를 바로 가져오기.

temp.get(first_name="철수")

temp.get(last_name="김")

 - Manager Query : DB작업들에 대한 메소드들을 제공해주는 객체(Manager)

 - Queryset : ModelBase 들의 집합으로 구성, 제너레이터 타입, Python Set[] 의 확장

 - Query문 만들 때 Queryset 사용


------------------------------------------------------------------------------------

+ Recent posts