반응형

1. JSON & Http Resquest & Response & Httpie

  • JSON 
    • Java Script Object Notation 의 약자
    • 데이터 송수신을 자바스크립트의 문법으로 표현된 객체로 수행할 수 있게 만든 가벼운 문자열 데이터 표현식
    • 자바스크립트를 사용하지 않아도 사용 가능하다!
    •  웹에서는 Server와 Client 사이에는 여러 항목을 주고 받음. /구조를 나타내는 HTML /스타일을 표현하는 CSS /논리를 구현하는 Javascript
    • 앞으로의 강의들은 데이터인 JSON 만 주고 받음!
  • JSON 문법 형식
    • Python 의 딕셔너리와 비슷한 구조
    • name : value
    • 숫자, 문자(열), Boolean, 배열, 객체 등으로 구성 가능 
    • JSON  데이터를 보낼 때에는 직렬화(Serialization) 과정을 거쳐 JSON 데이터를 문자열로 바꾸어 상대방에게 보낸다.
    • 데이터를 보낼 때에는 JSON  -> 문자열로 / 데이터를 받을 때에는 문자열 -> JSON으로 바꾸어 받는다.
json_example = { 
	"string_name": "something",
    "number_name": 3,
    "null_name": null,
    "bool_name": true
}
  • Python에서 JSON 사용하기
    • Python 딕셔너리 자료형을 반환해보자
import json //Json을 처리하는 라이브러리를 제공
diary = {
	"id": 3,
    "title": “멋쟁이사자처럼”,
    "body“: “2학기도 파이팅”
}

print(diary)
//{‘id’: 3, 'title': ‘멋쟁이사자처럼’, ‘body’: ‘2학기도 파이팅’}

print(type(diary))
//<class ‘dict’>
  • Dict to JSON 
    • JSON의 dumps 함수를 이용해 변환 진행
    • 데이터를 송신할 때 사용할 수 있다.
    • dic 이였던 자료형이 str로 변환
diary_s = json.dumps(diary)
print(diary_s) 
//{‘id’: 3, 'title': ‘멋쟁이사자처럼’, 'body': ‘2학기도 파이팅’}
print(type(diary_s)) 
//<class ‘str’>
  • JSON to Dict
    • JSON 의 load 함수를 이용해 변환을 진행
    • 데이터를 수신할 때 사용할 수 있다
    • Str 자료형이 dict로 다시 변환되었음을 볼 수 있다.
diary_b = json.loads(diary)
print(diary_b) 
//{‘id’: 3, 'title': ‘멋쟁이사자처럼’, 'body': ‘2학기도 파이팅’}
print(type(diary_b)) 
//<class ‘dict’>

Http Requsest & Response

  • 정의
    • Http란?
      • 웹 상에서 통신을 주고 받을 수 있는 주체, Client와 Server 그 중, Server의 역할은 Request 를 가공해서 처리해주는 역할
      • Web 상에서 지원하는 통신 규약을 Http
      • 한마디로 정의한다면?
        • HttpRequest : 요청에 대한 메타 정보를 가지고 있는 객체 
        • HttpResponse : 요청에 대한 메타 정보를 가지고 있는 객체
    • Django 에서 Http Method
GET POST
빈 입력공간 가져와 입력한 내용 처리
URL에 데이터 정보 포함 URL에 데이터 정보 포함 안함

        ▪ Django 에서 Rest FrameWork에서 Http Method

Method 기능
GET 요청받은 URL의 정보 검색하여 응답
POST 요청된 자원을 생성(CREATE)
DELETE 요청된 자원 삭제
PATCH 요청된 자원 일부 수정
OPTION 웹 서버에 지원된 메소드 종류 확인

 

 

 Django Rest FrameWork?

-> 장고 안에서 RESTful API 서버를 쉽게 구축할 수 있도록 도와주는 오픈 소스라이브러리

 

-Rest?

    -> HTTP 의 URL과 HTTP Method(GET, POST, PUT, DELETE)를 사용해서

         API 사용 가독성을 높인 구조화된 시스템 아키텍쳐(Framework)

 

-RESTful 아키텍쳐를 HTTP Method와 함께 사용해서 웹, 데스크탑 앱, 어플리케이션 까지 구동할 수 있는 서버를 만든다고 생각!

 

  • Django Rest Framework API Server에서는 JSON을 주고 받음
  • 서버 Response 종류 
    • 1XX (정보) -> 요청을 받았으며 프로세스를 계속한다.
    • 2XX(성공) -> 요청을 성공적으로 받았으며 인식했고 수용했다. 
    • 3XX(리다이렉션) -> 요청을 완료하기 위해 추가 작업 조치가 필요하다.
    • 4XX(클라이언트 오류) -> 요청의 문법이 잘못되었거나 요청을 처리할 수 없다.
    • 5XX(서버 오류) -> 서버가 명백히 유효한 요청에 대해 충족에 실패했다.

Httpie

- 요청을 Command Line으로 동작하는 파이썬 기반 프로그램 (=http client)

- 다른 http Client 보다 가볍고 설치하기 편하기 떄문에 사용

 

-httpie 설치

>>pip install --upgrade httpie

 

-httpie 명령어

>>http [flags] [METHOD] URL [ITEM[ITEM]]

 

flags : 옵션

▪ METHOD : HTTP METHOD

▪ URL : 요청이나 응답의 대상 URL

▪ ITEM : 처리할 값 (인자)

▪ POST / PUT : =로 표현

▪ GET : ==로 표현

 

▪ Httpie 명령어 사용 예시 

     ▪ GET

          http(GET) 대상주소 인자 ==값

 http (GET) example.org a==1 b==2
 http example.org a==1 b==2 


      ▪ PUT

           http(PUT) 대상주소 GET인자 ==값 PUT인자=값

 http PUT example.com a==1 b==2


▪ Get 인자가 있으면 쓰고 없으면 안쓴다. ▪ Put 인자가 있으면 쓰고 없으면 안쓴다.

 

2. CBV

-장고의 view

    - 호출 가능한 객체(callable object) 로 정의

        -> 함수 / 클래스

    - 함수와 클래스의 차이 : 함수 (상속x) / 클래스 (상속o)

    - 상속을 사용하는 이유는 ? 중복의 제거 / 코드의 재사용

 

따라서 CBV를 사용하는 이유는 상속을 사용해 코드를 더 간단하게 작성하기 위해 사용

 

-FBV(Function Based View)  : 함수 기반 뷰 

 

##실습하면서 익혀봅시다

순서 : 프로젝트 생성 -> 앱 생성 -> 템플릿 추가

 

가상환경 생성 및 활성화

$python -m venv myvenv

$ source myvenv/Scripts/activate

 

프로젝트 생성

$ django-admin startproject CBV

$ cd CBV

 

앱 생성 

$python manage.py startapp classBaseCrud

 

settings.py 에 앱 추가

INSTALLED_APPS = [
    'classBaseCrud',
]

 models.py 작성하기

- 클래스 생성

from django.db import models

# 클래스를 생성하여 제목, 생성일, 수정일, 본문 필드 작성

class ClassBlog(models.Model):
    title = models.CharField(max_length=100)
    created_at = models.DateTimeField(auto_now_add=True)
    #auto_now_add 옵션 : model이 최초 저장시에만 현재 날짜 적용
    updated_at = models.DateTimeField(auto_now=True)
    #auto_now 옵션 : 데이터가 저장 될 때마다 현재 날짜로 갱신
    body = models.TextField()

    def __str__(self):
        return self.title

-admin.py에 생성한 클래스 등록

from django.contrib import admin
from .models import ClassBlog

admin.site.register(ClassBlog)

-마이그레이션

$ python manage.py makemigrations
$ python manage.py migrate

 

views.py 작성하기

1) 사용할 모듈 추가 - CRUD

게시글 목록 ListView
새로운 게시글 생성 CreateView
게시글 상세 내용 DetailView
게시글 수정 UpdateView
게시글 삭제 DeleteView

    -Generic Views : 웹 개발 시 자주 사용하는 기능을 장고에서 미리 제공 / 외부 모듈 적용이 필요하다

 

      #사용할 모듈 추가 CRUD

from django.utils import timezone

from django.urls import reverse_lazy

from django.views.generic.list import ListView
#게시글 목록 보여줌

from django.views.generic.detail import DetailView
#게시글의 상세 내용을 보여줌

from django.views.generic.edit import CreateView, UpdateView, DeleteView
#게시글 생성, 수정, 삭제 

from .models import ClassBlog

2)모듈을 상속해 클래스 작성(classBaseCrud/views.py)

-CREATE

#CREATE
class BlogCreate(CreateView):
    model = ClassBlog
    fields = ["title", "body"]
    success_url = reverse_lazy('list')
    #reverse_lazy 
    #- redirect 와 같은 기능으로 , generic view에서 주로 사용
    #- reverse_lazy() 함수 사용 인자로 URL 이름을 넣어줌
    #- 작업이 성공적으로 완료되었을 경우 해당 URL로 이동

-READ

#READ
class BlogView(ListView):
    model = ClassBlog
    template_name = 'classBaseCrud/list.html'
    context_object_name = 'blog_list'
    # List Views
    #- Generi view 중 특정 모델의 리스트를 출력해주는 뷰
    #- 모델에 대한 쿼리가 필요하고(queryset)
    #- 어느 템플릿에 (template_name)
    #- 어떤 파라미터명으로 전달할지 (context_object_name) 를 정의
    #- 약속되어있는 html 이름을 사용하지 않고 작성하기 위함
    #- 해당 html을 사용할 class에 template_name을 설정하면 된다
    
    #context_object_name : 임의로 설정하여 기본적으로 설정되어있는 객체를 가져옴
class BlogRead(DetailView):
    context_object_name = 'blog'
    model = ClassBlog
    #DetailView
    #- 특정 모델의 특정 오브젝트에 대한 자세한 정보를 출력해주는 뷰
    #- 어떤 모델의 어떤 오브젝으를 어떤 템플릿에 전달할지 정의

-UPDATE

#UPDATE
class BlogUpdate(UpdateView):
    model = ClassBlog
    fields = ["title", "body"]
    success_url = reverse_lazy("list")

-DELETE

#DELETE
class BlogDelete(DeleteView):
    model = ClassBlog
    success_url = reverse_lazy("list")

앱 내부에 urls.py 생성 및 작성

- 작성할 클래스에 맞는 url path 작성

- (urls.py / classBaseCurd)

from django.urls import path
from .import views

#작성할 클래스에 맞는 url path 작성
urlpatterns = [
    path("", views.BlogView.as_view(), name='list'),
    #as_view : view를 하나 만들어서 이를 return
    #함수가 하나 만들어지는 것과 같음
    #클래스를 정의한 후 이에 해당하는 함수 만들어 사용하는 방식

    path("create/", views.BlogCreate.as_view(), name="create"),
    path("read/<int:pk>/", views.BlogRead.as_view(), name="read"),
    path("update/<int:pk>/", views.BlogUpdate.as_view(), name="update"),
    path("delete/<int:pk>/", views.BlogDelete.as_view(), name="delete"),
]

프로젝트 urls.py 에 앱 urls.py 추가

- (urls.py / CBV)

from django.contrib import admin
from django.urls import path, include
#django.urls 의 include 모듈 추가
#앱의 urls.py 파일을 프로젝트 urls.py에 추가
import classBaseCrud.urls
import classBaseCrud.views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(classBaseCrud.urls)),
]

templates 생성하기

- 수행 결과를 보여주는 HTML 템플릿이 존재해야하고 
ListView 는 블로그 리스트 HTML / CreateView, UpdateView 는 입력공간(form)을 갖는 HTML

DetailView는 상세 페이지 HTML / DeleteView 는 삭제 작업을 확인하는 HTML 필요

 

- Generic View 에서는 기본적으로 설정된 이름이 존재

- 다른 이름으로 HTML 을 작성하기 위해서는 추가 설정이 필요

 

View 이름 HTML 이름
ListView (소문자 모델)_list.html
CreateView (소문자 모델)_form.html
DetailView (소문자 모델)_detail.html
UpdateView (소문자 모델)_form.html
DeleteView (소문자 모델)_confirm_delete.html

 

##template폴더 구성할 때 template 안에 HTML 파일을 작성하는 게 아니라 App 이름의 폴더를 작성하고 그 안에 작성

앱 안에 templates라는 폴더를 만들고 그 안에 앱 이름으로 폴더를 만들어 그 안에 html를 만들어야함

#classblog_list.html

<!DOCTYPE html>
<html lang="ko" dir="ltr">
    <head>
        <meta charset="utf-8">
        <title>Class Base View</title>
    </head>
    <body>
        <a href="{% url 'create' %}"> 추가 </a>
        
        <br>
        
        {% for blog in blog_list %}
        <h2> {{ blog.title }} </h2>
        <h2> {{ blog.created_at }} </h2>
        <p> {{ blog.body }} </p>
        
        <a href="{% url 'read' blog.id %}"> 자세히보기 </a><br>
        <a href="{% url 'update' blog.id %}"> 수정 </a><br>
        <a href="{% url 'delete' blog.id %}"> 삭제 </a><br>
        {% endfor %}
    </body>
</html>

#classblog_form.html

<form method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="추가하기">
</form>

//HTTP POST, PUT, DELETE 🡪 {% csrf token %} 사용
//{{ form.as_p}} : view에서 전달한 form 객체를 템플릿 변수로 사용 / 폼의 각 필드를 p태그 안에 배치

#classblog_detail.html

<h1> 본문 자세히 보기 페이지 </h1>

<hr>

<h2> 제목 : {{ blog.title }} </h2>
<h4> 날짜 : {{ blog.created_at }} </h4>
본문 : {{ blog.body }}

#classblog_confirm_delete.html

<form method="POST">
    {% csrf_token %}
    <h2>진짜 지울거야?</h2>
    <br>
    <br>
    <input type="submit" value="삭제">
</form>

##결과

CREATE
DETAIL
UPDATE(수정)
DELETE
생성 후 리스트 목록

반응형

'Web > Django' 카테고리의 다른 글

[Django_심화]3 - viewset & router  (2) 2019.11.03
[Django_심화]2 - Rest, Serializer  (0) 2019.11.03
[6주차]Form  (0) 2019.03.06
[5.5주차]Faker  (0) 2019.03.05
[5주차]2.Pagination  (0) 2019.03.05
반응형

#Form -> model 형식에 맞는 입력 공간 (html form 의 한계성) / Django 기능 활용 (form 만들기 = model 만들기와 유사)

-form.py: html에서 보여지는 form / -models.py  : DB


1.blog app / forms.py(생성) 

 # Blog class를 기반으로 만들 것이기 때문에 blog 안에 form.py 생성/ models.py있으니까
from django import forms
from .models import Blog 
 
# 모델기반이 아니면 forms.Form
class BlogPost(forms.ModelForm):
    class Meta: #어떤 모델을 기반으로 한 입력공간, 그 모델 중에 어떤 항목 입력?
        model = Blog
        fields = ['title''body'
cs 



2.blog app/urls.py

1
 path('newblog/', views.blogpost, name='newblog'),
cs


3.blog app/views.py

from .forms import BlogPost
 
def blogpost(request):
    # 1. 입력된 내용 처리 : POST
    if request.method == 'POST':
        form = BlogPost(request.POST)
        if form.is_valid(): 
    #적절한 값이 잘 입력되었는지 확인 // 입력값이 형식에 맞게 입력되었으면 true ,문제가 있다면 false 반환.
            post = form.save(commit=False) #일단 저장하지 말고 form객체 말고 model 객체 접근
            post.pub_date = timezone.now() 
            post.save()
            return redirect('home')
    # 2. 빈 페이지 띄워주는 기능 : GET
    #new.html에 빈 페이지 띄우기
    else:
        form = BlogPost()
        return render(request, 'new.html', {'form': form})
cs


 



4.blogapp/templates/new.html



반응형

'Web > Django' 카테고리의 다른 글

[Django_심화]2 - Rest, Serializer  (0) 2019.11.03
[Django_심화]1 - 준비운동  (0) 2019.11.02
[5.5주차]Faker  (0) 2019.03.05
[5주차]2.Pagination  (0) 2019.03.05
[5주차]1.로그인,회원가입  (0) 2019.03.05
반응형

faker = 말 그대로 가짜 데이터


1.설치

1
2
USER@DESKTOP-SRO5U54 MINGW64 ~/Desktop/likelion2/second_assignment
$ pip install faker
cs


2.fake.py 생성 -> myvenv와 같은 위치에 파일 생성

<fake.py>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 가짜 데이터 생성 능력 있는 클래스 Faker import
from faker import Faker
 
myfake = Faker()
 
# Faker의 메소드로 어떤 종류의 가짜데이터를 뽑아낼지 결정
print("===========")
print(myfake.name()) # 가짜 이름 데이터 생성
print(myfake.address()) # 가짜 주소 데이터 생성 
print(myfake.text())
print(myfake.state())
print(myfake.sentence())
print(myfake.random_number())
print("===========")
cs


3.터미널 실행 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
USER@DESKTOP-SRO5U54 MINGW64 ~/Desktop/likelion2
$ python fake.py
===========
Dawn Werner
423 Benjamin Ridges Suite 803
New Michael, NV 06493
Reach strong rather important a.
Some stand war half back start. Something Congress interview himself something financial source.
Street human network reflect. Past gas ahead government.
Nevada
During as baby make leader really magazine among.
54
===========
(myvenv)
cs

 

#한국말로 출력 원할 때 -> 근데 .text/.state/.sentence는 생성하지 못함

1
myfake = Faker('ko_KR')
cs


#매번 바뀌는 데이터 X-> 가짜를 FIX하고 싶으면 

1
2
# Seed 파일
myfake.seed(1# 각각 가짜데이터의 데이터번호
cs


4. faker를 데이터 db에 저장, 삭제 가능 

반응형

'Web > Django' 카테고리의 다른 글

[Django_심화]1 - 준비운동  (0) 2019.11.02
[6주차]Form  (0) 2019.03.06
[5주차]2.Pagination  (0) 2019.03.05
[5주차]1.로그인,회원가입  (0) 2019.03.05
[4주차]2.blog-(3)  (0) 2019.03.05
반응형

<home.html> 의 블로그 글들 페이지네이션 하고 싶을 때 -> 방법은 많음


요약하자면

1.무슨 객체를 , 한 페이지 당 몇개씩 실을 것인지 결정 -> Paginator(object, num)

2.내가 원하는 페이지 갖고 오기                     -> 페이지네이터객체.get_page(갖고오고싶은 페이지번호)

3.갖고 온 페이지 html에 띄우기                     -> 페이지객체의 매소드함수 + template언어


#page 객체의 메소드 함수

-page.count() : 총 객체 수(총 블로그 글 개수)

-page.num_pages() : 총 페이지 개수

-page.page(n)  : n번째 페이지 리턴

-page.page_range() :(1부터 시작하는) 페이지 리스트 반환

-page.get_page(n) :n번째 페이지 갖고 오기

-page.has_next() : 다음페이지 있으면 true/ 없으면 false

-page.has_previous() : 이전 페이지 있으면 true/없으면 false

-page.previous_page_number() : 이전 페이지 번호 반환


1.blog app /views.py -> home.html이 있는 app에서 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from django.core.paginator import Paginator
 
def home(request):
    blogs = Blog.objects
    # 블로그 모든 글을 대상으로
    blog_list = Blog.objects.all()
    # 블로그 객체 세 개를 한 페이지로 자르기
    paginator = Paginator(blog_list, 3)
    # request된 페이지가 뭔지 알아내고 (request 페이지를 변수에 담아내고)
    page = request.GET.get('page')
    # request된 페이지를 얻어온 뒤 return 해준다
    posts = paginator.get_page(page)
    return render(request, 'blog/home.html', {'blogs': blogs, 'posts':posts})
 
cs


## 갑자기 한글 파일 깨짐 그럴 때는 base.html 에

1
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
cs


2.home.html 에서 사용 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{% extends 'base.html' %}
 
 
{% block content%}
 
{% for blog in posts %}
<div style="margin:30px auto 30px auto; display: block" class="container" >
    <div class="card">
    <div class="card-body">
    <h5 class="card-title">{{blog.title}}</h5>
    <h6 class="card-subtitle mb-2 text-muted">{{ blog.pub_date}}</h6>
    <class="card-text">{{blog.summary}}</p>
    <a href="{% url 'detail' blog.id %}" class="card-link">..more</a>
    </div>
    </div>
</div>
{% endfor %}
 
{#First Previews 3of4 Next Last#}
 
{#first previous#}
{% if posts.has_previous%}
<a href="?page=1">First</a>
<a href="?page={{posts.previous_page_number}}">Previous</a>
{% endif %}
{#3of4#}
<span>{{posts.number}}</span>
<span>of</span>
<span>{{posts.paginator.num_pages}}</span>
{#Next Last#}
{% if posts.has_next%}
<a href="?page={{posts.next_page_number}}">Next</a>
<a href="?page={{posts.paginator.num_pages}}">Last</a>
{% endif %}
{% endblock %}
 
cs


##container가 전부를 감싸는 오류 생김 -> div어디 감싸는지 endblock 어디에 넣어주는 지 잘 보쟈

반응형

'Web > Django' 카테고리의 다른 글

[6주차]Form  (0) 2019.03.06
[5.5주차]Faker  (0) 2019.03.05
[5주차]1.로그인,회원가입  (0) 2019.03.05
[4주차]2.blog-(3)  (0) 2019.03.05
[4주차]2.blog-(2)  (0) 2019.03.04
반응형

<로그인 기능 구현 >


1.accounts app 생성 

1
$python manage.py startapp accounts
cs


-> settings.py ->  app 목록 -> accounts 추가

1
'accounts.apps.AccountsConfig',
cs


2.template 만들기 -> login.html / signup.html =>  accounts/templates/accounts


-> signup.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{% extends 'base.html' %}
 
{% block content %}
 
<h1>Sign Up!</h1>
 
<form>
    Username:
    <br>
    <input name="username" type="text" value="">
    <br>
    Password:
    <br>
    <input name="password1" type="password" value="">
    <br>
    Confirm Password:
    <br>
    <input name="password2" type="password" value="">
    <br>
    <br>
    <input class="btn btn-primary" type="submit" value="Sign Up!">
</form>
 
{% endblock %}
cs


-> login.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{% extends 'base.html' %}
 
{% block content %}
 
<h1>Login</h1>
 
<form>
    Username:
    <br>
    <input name="username" type="text" value="">
    <br>
    Password:
    <br>
    <input name="password" type="password" value="">
    <br>
    <br>
    <input class="btn btn-primary" type="submit" value="Login">
</form>
 
{% endblock %}
cs


3. accounts/ views.py 에서 페이지 연결

1
2
3
4
5
6
7
8
9
10
11
from django.shortcuts import render
    
    # Create your views here.
    
    
    def signup(request):
        return render(request, 'accounts/signup.html')
    
    
    def login(request):
        return render(request, 'accounts/login.html')
cs



4.accounts/ulrs.py 생성해서 url 연결

1
2
3
4
5
6
7
8
from django.urls import path
from . import views
 
urlpatterns = [
    path('signup/', views.signup, name='signup'),
    path('login/', views.login, name='login'),
]
 
cs


5. 프로젝트 urls.py -> include로 연결

1
path('accounts/', include('accounts.urls')),
cs


6. navbar 에 login.html과 signup.html 연결될 링크 만들어줌 -> base.html

1
2
    <class="nav-item nav-link" href="{% url 'signup'%}">Signup</a>
    <class="nav-item nav-link" href="{% url 'login'%}">Login</a>
cs

<회원 가입 기능 구현하기>

1.template 수정하기 signup.html

1
2
3
<form method="POST" action="{% url 'signup'%}">
 
{% csrf_token %}
cs


##RESTful - HTTP method

-> GET - 데이터 조회(READ)

-> POST - 데이터 생성(CREATE)

-> PUT - 데이터 수정(UPDATE)

-> DELETE - 데이터 삭제(DELETE)


##{% csrf_toekn %} 

-> 보안 위해 사용하는 내용 


##form태그 안에 적어주어야 form을 submit 할 떄 같이 전송됨


2.view 수정하기 <accounts/views.py>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from django.contrib import auth
    
    # Create your views here.
    
    
def signup(request):
    if request.method == 'POST':
        if request.POST['password1'== request.POST['password2']:
            user = User.objects.create_user(
                request.POST['username'], password=request.POST['password1'])
            auth.login(request, user)
            return redirect('home')
    return render(request, 'accounts/signup.html')
    
    
cs


<로그인 기능 구현하기>

1.template 수정하기 <login.html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{% extends 'base.html' %}
 
{% block content %}
 
{% if error %}
{{ error }}
<br>
<br>
{% endif %}
 
<h1>Login</h1>
 
<form action="{% url 'login' %}" method="POST">
        {% csrf_token %} <!-- csrf 공격 방어하는 수단 for 보안 -->
    Username:
    <br>
    <input name="username" type="text" value="">
    <br>
    Password:
    <br>
    <input name="password" type="password" value="">
    <br>
    <br>
    <input class="btn btn-primary" type="submit" value="Login">
</form>
 
{% endblock %}
cs


2. accounts/views,py -> login 수정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def login(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
 
        user = auth.authenticate(request, username=username, password=password)
        if user is not None:
            auth.login(request, user)
            return redirect('home')
        else:
            return render(request, 'accounts/login.html', {'error''username or password is incorrect.'})
 
    else:
        return render(request, 'accounts/login.html')
cs


<logout 구현하기>

1.view 추가하기 (accounts/views.py)

1
2
3
4
5
def logout(request):
    if request.method == 'POST':
        auth.logout(request)
        return redirect('home')
    return render(request,'accounts/login.html')  
cs


2.url 추가하기(accounts/urls.py)

1
path('logout/', views.logout, name='logout'),
cs



<login/logou/signup 기능 navbar링크 걸기>

->(base.html)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <div class="container">
            <class="navbar-brand" href="{% url 'home' %}">Like Lion</a>
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup"
                aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
                <ul class="navbar-nav ml-auto">
                    <li class="nav-item">
                        <class="nav-item nav-link" href="{% url 'home' %}">HOME</span></a>
                    </li>
                    <li class="nav-item">
                        <class="nav-item nav-link" href="{% url 'portfolio' %}">Portfolio</a>
                    </li>
                    <li class="nav-item">
                        <class="nav-item nav-link" href="{% static '수료증 - 삼육대 - 오지수.pdf'%}">수료증</a>
                    </li>
                    {% if user.is_authenticated %}
                    <li class="nav-item dropdown">
                        <class="nav-link dropdown-toggle" id="navbarDropdown" role="button" data-toggle="dropdown"
                            aria-haspopup="true" aria-expanded="false">환영합니다. {{ user.username }} 님!</a>
                        <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                            <class="dropdown-item" href="{% url 'new' %}">글쓰기</a>
                            <class="dropdown-item" href="javascript:{document.getElementById('logout').submit()}">Logout</a>
                            <form id="logout" method="POST" action="{% url 'logout' %}">
                                {% csrf_token %} <input type="hidden" />
                            </form>
                        </div>
                    </li>
                    {% else %}
                    <li class="nav-item">
                        <class="nav-item nav-link" href="{% url 'signup' %}">Signup</a>
                    </li>
                    <li class="nav-item">
                        <class="nav-item nav-link" href="{% url 'login' %}">Login</a>
                    </li>
                    {% endif %}
                </ul>
            </div>
        </div>
    </nav>
cs




요렇게 하면 ~

로그인시 화면 이렇게 출력~ hidden도 된다 

반응형

'Web > Django' 카테고리의 다른 글

[5.5주차]Faker  (0) 2019.03.05
[5주차]2.Pagination  (0) 2019.03.05
[4주차]2.blog-(3)  (0) 2019.03.05
[4주차]2.blog-(2)  (0) 2019.03.04
[4주차]2.blog-(1)  (0) 2019.03.04
반응형

<portfolio app 만들기>


1. app 만들기

1
$python manage.py startapp portfolio
cs


<settings.py>-> portfolio app 추가

1
INSTALLEDS_APP=['portfolio.apps.PortfolioConfig',]
cs


2. template 만들기-> portfolio 폴더 안-> templates폴더 생성 -> portfolio폴더 생성-> portfolio.html


3. view 만들기 -> portfolio 폴더 안 -> views.py

1
2
def portfolio(request):
    return render(request, 'portfolio/portfolio.html')
cs


4.url 수정 -> secondproject 폴더 안 -> urls.py

1
2
3
4
import portfoilo.views
urlpatterns = [
    path('portfoilo/', portfolio.views.portfolio, name='portfolio'),
]
cs




##불편함 해결1 : html파일 중복 해결


1. second_assignment project 안 -> templates 폴더 -> base.html (기본 골격이 되는 html)

-> 계속 들어가는 코드부분만 지워버리고 밑에 코드 채워줌

1
2
3
4
<div class="container">
{% block content%}
//변경될 내용 들어감
{% endblock %}
</div>
cs


2. home.html -> base.html과 중복되는 내용 부분 날려줌

<home.html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{% extends 'base.html'%}
{% block content %}
<br>
{% for blog in blogs.all %}
<br>
    <div class="container">
        <a href="{% url 'detail' blog.id %}">
            <h1>{{ blog.title }}</h1>
        </a>    
        <p>{{ blog.pub_date }}</p>
        <p>{{ blog.summary }}<a href="{% url 'detail' blog.id %}">....more</a></p>
    </div>
{% endfor %}
{% endblock %}
cs


3. django에게 우리가 기본으로 쓸 html 파일의 위치를 알려주는 작업 해야함

<settings.py> -> TEMPLATES -> DIRS

1
'DIRS': ['secondproject/templates'],
cs


4. portfolio.html 에 navbar 넣어보기 

1
2
3
4
5
{% extends 'base.html' %}
 
{% block content%}
<h1>포토폴리오 페이지 입니다</h1>
{% endblock %}
cs


##불편함 해결하기 2 : url 정리

-> blog path들은 blog 폴더 안에서 해결, portfolio관련 path들은 portfolio 폴더 안에서 해결하게 정리


1. blog 폴더 안 -> urls.py 파일

2. secondproject 안 -> urls.py 내용 복사 -> blog /urls.py에 넣어줌

3. blog 관련 path들과 import 관련 내용 싹 다 정리

<blog/urls.py>

1
2
3
4
5
6
7
8
9
10
from django.urls import path
from . import views
 
 
urlpatterns = [
    path('<int:blog_id>/', views.detail, name='detail'),
    path('new/', views.new, name='new'),
    path('create/', views.create, name='create'),
]
 
cs



<portfolio/urls.py> 

1
2
3
4
5
6
from django.urls import path
from . import views
 
urlpatterns = [
     path('portfolio/', views.portfolio, name='portfolio'),
]
cs


<프로젝트 폴더 안 /urls.py> -> blog관련/portfolio url정리/

1
2
3
4
5
6
7
8
9
10
11
from django.contrib import admin
from django.urls import path, include
import blog.views
import portfolio.views
 
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', blog.views.home, name='home'),
    path('blog/', include('blog.urls')),
    path('portfolio/', include('portfolio.urls')),
]
cs



<portfolio static 이미지로 꾸미기>

1. https://getbootstrap.com/docs/4.3/examples/album/ 에서 소스코드 main부분만 가져오고 필요없는 것 지우기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{% extends 'base.html' %}
 
{% block content%}
<h1>포토폴리오 페이지 입니다</h1>
<main role="main">
 
  <section class="jumbotron text-center">
    <div class="container">
      <h1 class="jumbotron-heading">travel destination</h1>
      <class="lead text-muted">likelion at sahmyook ohjisu</p>
      <p>
        <a href="{% url 'home'%}" class="btn btn-primary my-2">home</a>
        <a href="#" class="btn btn-secondary my-2">new destination</a>
      </p>
    </div>
  </section>
 
<div class="album py-5 bg-light">
    <div class="container">
 
      <div class="row">
        <div class="col-md-4">
          <div class="card mb-4 shadow-sm">
            <svg class="bd-placeholder-img card-img-top" width="100%" height="225" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: Thumbnail"><title>Placeholder</title><rect width="100%" height="100%" fill="#55595c"></rect><text x="50%" y="50%" fill="#eceeef" dy=".3em">Thumbnail</text></svg>
            <div class="card-body">
              <class="card-text">설명</p>
              <div class="d-flex justify-content-between align-items-center">
                <div class="btn-group">
                  <button type="button" class="btn btn-sm btn-outline-secondary">View</button>
                  <button type="button" class="btn btn-sm btn-outline-secondary">Edit</button>
                </div>
                <small class="text-muted">9 mins</small>
              </div>
            </div>
          </div>
        </div>
        </div>
    </div>
</div>
 
</main>
{% endblock %}
cs


2. static file = 정적 파일 (css, js, image)

#Django는 static 파일을 2개로 구분

-> static : 웹 서비스를 위해 개발자가 준비해두는 파일

->  media : 웹 서비스 이용자들이 업로드 하는 파일 


<portfolio 폴더 안 -> static 폴더 -> 사진 한장 삽입>


<settings.py -> 코드 추가> : django 프로젝트에 static 폴더라는게 생겼다는 것 알려줌

1
2
3
4
5
6
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'portfolio''static')
]
 
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
 
cs

->STATICFILES_DIRS : static 파일들이 들어있는 경로 적어줌

->STATIC_ROOT : static 파일 한곳에 모아줄 위치 나타냄


<static  파일들 한곳에 모아주는 명령어 입력>

1
$python manage.py collectstatic
cs


<portfolio.html 에 static 띄우기>

-> main태그 위에 넣어줌

1
{% load staticfiles %}
cs


-> img  삽입

1
<img src="{% static 'siba.jpg' %}" alt="">
cs


## 추가 연습 : navbar 수료증 클릭 시 수료증 띄우기


1. 프로젝트 폴더 안에 static 폴더 생성


2. 그 안에 pdf 파일 


3..settings.py 에 STATICFILES_DIRS 안에 

1
os.path.join(BASE_DIR, 'secondproject''static')
cs


4. base.html 파일에 

1
 {% load staticfiles %}
cs


5.templates/base.html의 navbar의'수료증'에 링크연결 

1
<class="nav-item nav-link" href="{% static '수료증 - 삼육대 - 오지수.pdf'%}">수료증</a>
cs


 ##강의에서는 python manage.py collectstatic 하라고 하는데 하면 overwriting 된다고 안된다 . 머지..싶지만 안하니까 잘됨 ><



<모델 이용해서 이미지 업로드 , portfolio페이지에 띄워보기>


1., <settings.py> media 설정

1
2
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
cs


2.프로젝트 폴더 내 urls.py 수정

1
2
3
4
5
from django.conf import settings
from django.conf.urls.static import static
...
...
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
cs


3.portfolio폴더 -> models.py 

1
2
3
4
5
6
7
class Portfolio(models.Model):
    title = models.CharField(max_length=255)
    image = models.ImageField(upload_to='images/')
    description = models.CharField(max_length=500)
 
    def __str__(self):
        return self.title
cs


##DB 안에 데이터 구성하는 설계도 : django documentation 보면 잘 나와있음

=>https://docs.djangoproject.com/ko/2.1/topics/db/models/


4.migration

1
2
3
4
5
$python manage.py makemigrations
 
$python manage.py migrate
 
$pip install Pillow
cs


5.django에게 새로운 모델 생겼다고 알려줘야함 -> portfolio 폴더 안 admin.py 


1
2
3
4
5
6
from django.contrib import admin
from .models import Portfolio
 
admin.site.register(Portfolio)
# Register your models here.
 
cs


6. view 수정하기(portfolio app-> views.py)

1
2
3
4
5
6
7
8
from django.shortcuts import render
from .models import Portfolio
 
# Create your views here.
 
def portfolio(request):
    portfolios = Portfolio.objects
    return render(request, 'portfolio/portfolio.html', {'portfolios': portfolios})
cs


7.template 수정하기<portfolio.html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div class="album py-5 bg-light">
  <div class="container">
      <div class="row">
      {% for portfolio in portfolios.all %}
        <div class="col-md-4">
          <div class="card mb-4 shadow-sm">
            <img class="card-img-top" src="{{ portfolio.image.url }}" alt=" Card image cap">
            <div class="card-body">
              <h4>{{ portfolio.title }}</h4>
              <class="card-text">{{ portfolio.description }}</p>
            </div>
          </div>
        </div>
    {% endfor %}
    </div>
  </div>
</div>
cs


반응형

'Web > Django' 카테고리의 다른 글

[5주차]2.Pagination  (0) 2019.03.05
[5주차]1.로그인,회원가입  (0) 2019.03.05
[4주차]2.blog-(2)  (0) 2019.03.04
[4주차]2.blog-(1)  (0) 2019.03.04
[4주차]1.pk, path converter, get_object_or_404  (0) 2019.03.03
반응형

<detail.html 생성&연결>

1. template 추가하기 (blog/templates/blog -> detail.html)

-> home.html 똑같이 복사해서 {%for blog in blogs.all %} 지우고 확인 메세지 적음

1
<h1>디테일 페이지입니다.</h1>
cs


2. views.py 수정 (detail.html 템플릿 연결)


1
2
3
4
5
6
7
8
9
10
11
12
from django.shortcuts import render, get_object_or_404
from .models import Blog
 
def home(request):
    blogs = Blog.objects
    return render(request, 'blog/home.html', {'blogs': blogs})
 
def detail(request, blog_id):
    blog_detail = get_object_or_404(Blog, pk=blog_id)
    return render(request, 'blog/detail.html', {'blog': blog_detail})
# Create your views here.
 
cs


##get_object_or_404 : object를 가져오고 없으면 404 에러 띄워라 /모델명(대문자로 시작) + blog 게시글 id 값

   detail 함수는 request,blog_id를 함께 받아 해당 데이터 넘겨줌

   model에서 id기준으로 데이터 가져와 있으면 보여주고 없으면 404 에러

   id값은 기본적으로 django가 기본으로 만들어줌 


3. url config 만들기 -> path 추가 (project폴더 안 -> urls.py)

1
2
3
4
urlpatterns = [
    path('blog/<int:blog_id>',blog.views.detail, name='detail'),
]
 
cs


4. template 수정하기

<detail.html>

1
2
3
4
5
<div class="container jumbotron">
    <h1>{{ blog.title }}</h1>
    <p>{{ blog.pub_date }}</p>
  <p>{{ blog.body }}</p>
</div>
cs


-> 127.0.0.1:8000/blog/blog_id(int)로 접속하면 게시글에 detail로 들어가고 int값이 없으면 404에러 나온다


5. 링크 달기 

<home.html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<html>
<head>
{% comment %} bootstrap4 CSS CDN 부분 {% endcomment %}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
{% comment %} bootstrap4 js관련 CDN {% endcomment %}
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  <div class="container">
      <class="navbar-brand" href="{% url 'home'%}">Like Lion</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
        </button>
      <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
        <div class="navbar-nav ml-auto">
          <class="nav-item nav-link active" href="{% url 'home'%}">Home</a>
        <class="nav-item nav-link" href="#">Blog</a>
        <class="nav-item nav-link" href="#">수료증</a>
            </div>
    </div>
    </div>
</nav>
 
{% for blog in blogs.all %}
    <div class="container">
        <a href="{% url 'detail' blog.id %}">
            <h1>{{ blog.title }}</h1>
        </a>    
        <p>{{ blog.pub_date }}</p>
        <p>{{ blog.body }}</p>
    </div>
{% endfor %}
</body>
</html>
cs


<detail.html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  <div class="container">
      <class="navbar-brand" href="{% url 'home' %}">Like Lion</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
        </button>
      <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
        <div class="navbar-nav ml-auto">
          <class="nav-item nav-link active" href="{% url 'home' %}">Home</a>
        <class="nav-item nav-link" href="#">Blog</a>
        <class="nav-item nav-link" href="#">수료증</a>
            </div>
    </div>
    </div>
</nav>
 
<h1> detail 페이지 입니다 </h1>
<div class="container jumbotron">
    <h1>{{ blog.title }}</h1>
    <p>{{ blog.pub_date }}</p>
    <p>{{ blog.body }}</p>
    <a href="{% url 'home' %}">돌아가기</a>
</div>
 
</body>
</html>
cs

<블로그 본문 내용 줄여서 보여주기>


1.models.py (클래스에 정의된 body에서 100 글자만 출력)

1
2
     def summary(self):
        return self.body[:100]
cs


2.template 고치기 -> home.html -> {{blog.body}} => {{blog.summary}} ->잘린것처럼 보이니 ...more추가

1
<p>{{ blog.summary }}<a href="{% url 'detail' blog.id %}">....more</a></p>
cs


<글 작성할 수 있는 페이지 만들기>

#제목과 본문 내용을 입력받아야함

1. new.html 생성 -> home.html navbar만 복사 -> 글쓰기 링크 생성

1
<class="nav-item nav-link" href="#">글쓰기</a>
cs


2. form 태그 이용해 글 작성할 수 있게 만들어줌

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<br>
<div class="container">
    <form action="">
      <h4>제목: </h4>
      <input type="text" name="title">
      <br>
      <br>
      <h4>본문: </h4>
      <textarea cols=40 rows=10 name="body"></textarea>
      <br>
      <br>
      <input class="btn btn-dark" type="submit" value="제출하기">
  </form>
</div>
cs


3. views.py & url 설정 & template 링크 넣기 

-><views.py>

1
2
def new(request):
    return render(request, 'blog/new.html')
cs


->urls.py

1
path('blog/new/', blog.views.new, name='new'),
cs


->.html에 링크 넣어야할 부분에 

1
{% url 'new' %}
cs



<제출하기 버튼 작동하게 하기>


1. <views.py> :추가된 것

1
2
3
4
5
6
7
8
9
10
11
12
13
from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
 
from .models import Blog
# Create your views here.
 
def create(request):
    blog = Blog()
    blog.title = request.GET['title']
    blog.body = request.GET['body']
    blog.pub_date = timezone.datetime.now()
    blog.save()
    return redirect('/blog/' + str(blog.id))
cs


#

-blog.pub_date :입력한 시간이 자동으로 넘어감/ timezone이라는 패키지를 사용해 import

-redirect  : 요청을 처리하고 보여주는 페이지/ 

-render: '요청이 들어오면 이 html 파일을 보여줘 라는 녀석' <-> redirect: '요청을 들어오면 저쪽 url로 보내버려' 

2.url 설정

1
path('blog/create/', blog.views.create, name='create'),
cs


3. template 수정(new.html -> form 태그)

1
<form action="{% url 'create' %}">
cs




####여기까지완료하면 글쓰기 버튼까지 만들기 완료 

반응형

'Web > Django' 카테고리의 다른 글

[5주차]1.로그인,회원가입  (0) 2019.03.05
[4주차]2.blog-(3)  (0) 2019.03.05
[4주차]2.blog-(1)  (0) 2019.03.04
[4주차]1.pk, path converter, get_object_or_404  (0) 2019.03.03
[3.5주차]Bootstrap  (0) 2019.03.03
반응형

<blog 만들기>

1. 기본셋팅 ~url config 까지

-> 가상환경 구축

1
 $ python -m venv myvenv
cs

-> 가상환경 실행

1
 $ source myvenv/Scripts/activate
cs

-> django 설치

1
 $ pip install django
cs


-> 프로젝트 시작 

1
$ django-admin startproject secondproject 
cs

 -> app 만들기(프로젝트 안에) 

1
$python manage.py startapp blog 
cs


-> settings.py 에 app 알려주기

1
2
3
INSTALLED_APPS[
'blog.apps.BlogConfig',
]
cs

 -> blog app 안에 templates 폴더 ->blog 폴더 -> home.html 생성 (bootstrap cdn도 설정해주기)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body>
<ul class="nav">
  <li class="nav-item">
    <a class="nav-link active" href="#">Active</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</body>
</html>
cs


##navbar을 더 이쁘게 만들어 보고 싶다 하면 요렇게

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  <div class="container">
      <a class="navbar-brand" href="#">Like Lion</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
        </button>
      <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
        <div class="navbar-nav ml-auto">
          <a class="nav-item nav-link active" href="#">Home</a>
        <a class="nav-item nav-link" href="#">Blog</a>
        <a class="nav-item nav-link" href="#">수료증</a>
            </div>
    </div>
    </div>
</nav>
cs


-> blog app 안 views.py 에서 함수 설정

1
2
3
4
from django.shortcuts import render
 
def home(request):
    return render(request,'blog/home.html')
cs



-> 프로젝트 안 urls.py에서 urlconfig

1
2
3
4
5
6
7
8
9
from django.contrib import admin
from django.urls import path
import blog.views
 
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', blog.views.home, name='home'),
]
 
cs



2. model 만들기(blog 폴더 내 -> models.py)  

->순서 : models,py 에서 코드 작성 -> $python manage.py makemigrations (migration 만들기) -> $python manage.py migrate(데베적용)


->model : 제목 / 본문/ 작성일자  <models.py>

1
2
3
4
class Blog(models.Model):
    title = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    body = models.TextField()
cs


##migrate가 뭔데?

Django는 python으로 작동하는 웹 프레임워크이지만 DB(데이터베이스)의 경우는 그렇지 않음

그래서 우리가 내린 python 코드를 DB가 알아 듣게 설명을 해줘야하는 작업이 필요

위의 makemigrations는 내가 짠 파이썬 코드를 DB가 알아들을수 있게 번역하는 명령어이고, 

migrate는 DB에 그 내용을 적용하라는 명령어


->model 잘 만들어 졌는지 확인하려면 /admin 페이지에서 확인 


3. admin 만들기 

1
2
3
4
5
$ python manage.py createsuperuser
Username (leave blank to use 'user'): jisu
Email address: 282532@likelion.org
Password: wltn2548
Password (again): wltn2548
cs

만들어진 superuser로 로그인하면 admin에 들어가 수 있음 요렇게


어 근데 아직 admin에게 알려주지 않아서 blog라는 model이 존재 하지 않음 -> admin에 model 등록하기


-> blog 폴더 -> admin.py 

2줄 :같은 폴더 위치에 있는 models라는 파일에 , Blog라는 클래스 가져와

4줄 : admin 이라는 site에 Blog라는 클래스 등록

1
2
3
4
5
6
from django.contrib import admin
from .models import Blog
 
admin.site.register(Blog)
# Register your models here.
 
cs


새로고침 해보면 blog 객체 생긴게 보임!

아까 만들었던 blog 객체 저장하면 됨


##admin 페이지에서 글 제목 표시 하는 방법 : blog->models.py -> blog class 수정

## def 꼭 들여쓰기 해야함 안하면 에러나용

1
2
3
4
5
6
7
class Blog(models.Model):
    title = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    body = models.TextField()
 
    def __str__(self):
        return self.title
cs



-> model에서 데이터 가져오기 <views.py> 파일 수정해줘야함

1
2
3
4
5
6
7
8
from django.shortcuts import render
from .models import Blog
 
def home(request):
    blogs = Blog.objects
    return render(request, 'blog/home.html', {'blogs': blogs})
# Create your views here.
 
cs



##Blog를 import 해줌 / Blog.objects(admin 페이지에서 확인했던 blog안 데이터)-> blogs라는 변수에 넣어줌 

   render -> blogs라는 변수를 template에서 쓸때 blogs라고 해서 가져오겠다고 이름 지어줌


->template 수정하기 {{}}->home.html에 삽입

1
2
3
4
5
6
7
{% for blog in blogs.all %}
    <div class="container">
        <h1>{{ blog.title }}</h1>
        <p>{{ blog.pub_date }}</p>
        <p>{{ blog.body }}</p>
    </div>
{% endfor %}
cs



여기까지하면 게시글 작성까지 완료됨 ^^

반응형

'Web > Django' 카테고리의 다른 글

[4주차]2.blog-(3)  (0) 2019.03.05
[4주차]2.blog-(2)  (0) 2019.03.04
[4주차]1.pk, path converter, get_object_or_404  (0) 2019.03.03
[3.5주차]Bootstrap  (0) 2019.03.03
[3주차]model & admin  (0) 2019.03.03

+ Recent posts