반응형

1. 선택자 정리 

 -> CSS에서는 스타일링 해줄 요소를 선택자로 결정 

 

 -태그 이름 

1
2
3
4
/* 모든 <h1> 태그 */
h1 {
  color: orange;
}
cs

 

 

-클래스 / 아이디 선택자

1
2
3
4
5
6
7
8
9
/* 'important'라는 클래스를 갖고 있는 모든 태그 */
.important {
  color: orange;
}
 
/* 'favorite'라는 아이디를 갖고 있는 태그 */
#favorite {
  color: blue;
}
cs

 

-자식 선택자

1
2
3
4
5
/* 'div1' 클래스를 갖고 있는 요소의 자식 중 모든 <i> 태그 */
.div1 i {
  color: orange;
}
 
cs

 

-직속 자식(direct children)

1
2
3
4
/* 'div1' 클래스를 갖고 있는 요소의 직속 자식 중 모든 <i> 태그 */
.div1 > i {
  color: orange;
}
cs

 

-복수 선택

1
2
3
4
/* 'two' 클래스를 가지고 있는 태그 모두와 'four' 클래스를 가지고 있는 태그 모두 선택 */
.two, .four {
  color: orange;
}
cs

 

-여러 조건 

1
2
3
4
5
6
7
8
9
10
/* 'outside' 클래스를 갖고 있으면서 'one' 클래스도 갖고 있는 태그 */
.outside.one {
  color: blue;
}
 
/* 'inside' 클래스를 갖고 있으면서 'two' 클래스도 갖고 있는 태그 */
.inside.two {
  color: orange;
}
 
cs

 

-Pseudo-class (가상 클래스) -> :(클론) 사용하여 가상 클래스 선택

 

-> n번째 자식

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
/* .div1의 자식인 <p> 태그 중 3번째 */
.div1 p:nth-child(3) {
  color: blue;
}
 
/* .div1의 자식인 <p> 태그 중 첫 번째 */
.div1 p:first-child {
  color: red;
}
 
/* .div1의 자식인 <p> 태그 중 마지막 */
.div1 p:last-child {
  color: green;
}
 
/* .div1의 자식 중 마지막 자식이 아닌 <p> 태그 */
.div1 p:not(:last-child) {
  font-size: 150%;
}
 
/* .div1의 자식 중 첫 번째 자식이 아닌 <p> 태그 */
.div1 p:not(:first-child) {
  text-decoration: line-through;
}
 
cs

 

-> 마우스 오버(hover)

1
2
3
4
5
6
7
8
h1 {
  color: orange;
}
 
/* 마우스가 <h1> 태그에 올라갔을 때 */
h1:hover {
  color: green;
}
cs
 
2. CSS 상속(부모 요소의 속성들을 자식들한테 넘겨줌 -> div에 속성을 주면 밑에있는 자식들 까지 상속되어 모두 바뀜)

 

-상속되는 속성들 colorfont-family/ font-size/ font-weight/ line-height/ list-style/ text-align/ visibility

-항상 상속되는 것은 아님 (ex) <a>태그에는 color속성 상속 X => 억지로 받아오려면 inherit 값 사용

 

1
2
3
4
.div2 a {
  color: inherit;
}
 
cs

 

3. CSS 우선 순위 

-순서 : 똑같은 선택자가 나중에 또 나오면, 이전에 나온 스타일을 덮어 쓰게 됨

 

-명시도(specificity)에 따라 우선순위 결정

a.인라인 스타일 (가장 우선순위 높음)

b. 선택자에 id 多 우선 순위 높음

c. 선택자에 class , attribute , pseudo-class 多 우선 순위 높음

d. 그냥 요소(가상요소) 많은 순 

 

 

4. CSS 다양한 단위

-px : 절대적인 값 / 다른 요소의 값에 영향 x

 

-rem : 상대적인 값 / html 태그의 font-size 영향 받음 / 2rem : html 태그의 font-size X2

 

-em : 상대적인 값/ 자기 자신의 font-size 기준/ 자기의 size를 따로 정해주지 않았다면 상위 요소에서 상속받은 값 기준

 

-%(퍼센트) : 상대적인 값 / 어떤 항목에 쓰이냐에 따라 다른 기준 적용 / ex) font-size에서 %사용 시 곱해주는 방식 계산

 

1
2
3
4
5
6
7
8
9
10
11
.container {
  font-size: 20px;
  background-color: lime;
}
 
.text {
  font-size: 180%; /* 상위 요소인 container의 font-size * 1.8 = 36px */
  background-color: skyblue;
  margin: 0;
}
 
cs

 

     / margin, padding 단위로 사용 -> 상위 요소 width 기준 계산 , margin-top , padding-bottom 등 상하 속성 조절 시 상위요소 height가 아닌 width 기준으로 계산

1
2
3
4
5
6
7
8
9
.container {
  width: 200px;
  background-color: lime;
}
 
.text {
  padding-left: 30%; /* 상위 요소의 width * 0.3 = 60px */
}
 
cs

 

-참고 : https://webdesign.tutsplus.com/ko/tutorials/comprehensive-guide-when-to-use-em-vs-rem--cms-23984

반응형

'Web > HTML & CSS' 카테고리의 다른 글

8. Positioning  (0) 2019.03.21
7. display  (0) 2019.03.19
5. BOX Model -(2)  (0) 2019.03.12
5. BOX Model -(1)  (0) 2019.03.03
4. text 스타일링  (0) 2019.02.27
반응형

1. 박스 꾸미는 다른 방법 

 

-border-radius : 요소 모서리 둥글게 만듬 /크면 수록 둥글게 /개별 설정도 가능 

1

2

3

4

5

6

.div1 {

  border: 1px solid green;

  border-radius: 5px;

  margin-bottom: 20px;

}

 

cs

 

-background-color : 배경색 지정 

    

1

2

3

h1 {

  background-color: #4d9fff;

}

cs

 

-페이지 전체 배경색 : <body>태그 -> background-color 속성 /투명 : transparent 설정

    

1

2

3

4

5

6

7

h1 {

  background-color: white;

}

h2 {

  background-color: transparent

}

cs

 

-box-shadow : 요소에 그림자 /기본 : none / 위치 설정(가로, 세로 위치) /기본 (검정) 변경하고 싶을 써줌

 

    

1

2

3

4

5

6

.div1 {

  background-color: #eeeeee;

  width: 400px;

  height: 300px;

  box-shadow: 40px(가로) 10px(세로) 10px(흐림정도:blur) 20px(그림자 크기:spread) #4d9fff();

}

Colored by Color Scripter

cs


2. box-sizing

-box sizing 에서 항상 테두리와 패딩을 고려해서 게산을 해줘야 한다

-> 해결책 : box-sizing 속성 : border-box

                 따로 설정해주지 않으면 기본값은 content-box -> 이걸 border-box

               -> width height 테두리와 패딩 , 내용물을 모두 포함한 길이가

               -> 모든 요소에 나타내는 *속성 사용

1
2
3
4
5
6
7
8
9
10
{
  box-sizing: border-box;
}
.div1 {
  border: 10px solid red;
  width: 300px;
  height: 200px;
  margin-bottom: 50px;
}\
 
cs

3. background 이미지

- background-repeat : 이미지 반복시킬 것인지, 아닌지, 어떻게 반복할지

1
2
3
4
5
6
7
8
9
10
11
12
13
14
div{
/*반복하지 않음*/
background-repeat: no-repeat;
/*가로 방향으로만 반복*/
background-repeat: repeat-x;
/*세로 방향으로만 반복*/
background-repeat: repeat-y;
/*가로와 세로 모두 반복*/
background-repeat: repeat;
/*반복할 수 있는 만큼 반복한 뒤, 남는 공간은 이미지 간의 여백으로 배분*/
background-repeat: space;
/*반복할 수 있는 만큼 반복한 뒤, 남는 공간은 이미지 확대를 통해 배분*/
background-repeat: round;
}
cs

- background-size

1
2
3
4
5
6
7
8
9
10
11
12
13
div{
/* 원래 이미지 사이즈대로 출력 */
background-size: auto;
/* 화면을 꽉 채우면서, 사진 비율을 유지 */
background-size: cover;
/* 가로, 세로 중 먼저 채워지는 쪽에 맞추어서 출력 */
background-size: contain;
/* 픽셀값 지정 (가로: 30px, 세로: 50px로 설정) */
background-size: 30px 50px;
/* 퍼센트값 지정 (가로: 부모 요소 width의 60%, 세로: 부모 요소 height의 70%로 설정) */
background-size: 60% 70%;
}
 
cs

-background-position : 배경 이미지의 위치를 정해주는 속성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 단어로 지정해주기 (가로: left, center, right, 세로: top, center, bottom) */
/* 아래와 같은 총 9개의 조합이 가능 */
div{
background-position: left top;
background-position: left center;
background-position: left bottom;
background-position: right top;
background-position: right center;
background-position: right bottom;
background-position: center top;
background-position: center center;
background-position: center bottom;
/* 퍼센트로 지정해주기 (가로: 전체 width의 25% 지점, 세로: 전체 height의 75% 지점 ) */
background-position: 25% 75%;
/* 픽셀로 지정하기 (가로: 가장 왼쪽 가장자리에서부터 오른쪽으로 100px 이동한 지점, 세로: 가장 상단 가장자리에서 아래로 200px 이동한 지점) */
background-position: 100px 200px;
}
cs

반응형

'Web > HTML & CSS' 카테고리의 다른 글

7. display  (0) 2019.03.19
6. CSS 활용  (0) 2019.03.12
5. BOX Model -(1)  (0) 2019.03.03
4. text 스타일링  (0) 2019.02.27
2. class & id & div  (0) 2019.02.27
반응형

#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

+ Recent posts