깃에서 제외할 파일을 지정할 때는 .gitignore 파일에서 제외할 부분을 목록으로 작성해서 제외시켰었다.

(https://practice-a-lot.tistory.com/26)


이번에는 폼을 통해 저장된 사진을 깃에서 제외하는 방법이다.

동일하게 .gitignore 파일에서 작성한다.


1) *.jpg *.pgn 형태로 입력하면 해당 확장자에 걸리는 모든 사진을 추출


1
2
3
db.sqlite3
*.jpg
*.png
cs


문제점은 제외하지 말아야할 사진도 포함되므로 좋은 방법이 아니다.



2) 사진이 저장된 미디어 폴더를 지정


1
2
db.sqlite3
media/
cs



'코딩 연습 > Github' 카테고리의 다른 글

깃에서 필요 없는 것 빼기  (0) 2018.10.11
블로그 이미지

쵸잇

,

텍스트와 다르게 이미지를 저장하려면 많은 수고가 든다.




1) Settings.py에서 이미지 파일을 저장베이스 폴더(media) 경로를 설정한다.


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



2) Urls.py에서 개발 중미디어 파일(이미지, 비디오 등)을 다루기 위한 세팅

(단, DEBUG 상태에서만 가능하도록 if문을 별도로 작성)


1
2
3
4
5
6
from django.conf import settings
from django.conf.urls.static import static
 
if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
cs



3) Models.py에서 이미지 필드 만들기


1
image = models.ImageField()
cs


*이미지 필드 사용시 Pillow(https://pillow.readthedocs.io/en/latest/)라는 라이브러리 설치가 migrate 과정에서 요구된다.

(내가 올리는 이미지 파일의 포맷을 도와준다)



4) Forms.py에서 이미지 필드 지정하기


1
2
3
4
5
6
class Form(ModelForm):
     class Meta:
         model = 
         fields = (
             'image'
         )
cs



5) 템플릿에서 에 이미지 파일을 입력 받기 위해 이미지 전송을 위한 별도의 속성을 추가한다


1
<form enctype="multipart/form-data" method="post" action="">
cs



4) View에서 폼을 통해 입력 받은 이미지를 폼에 두고자 이미지 소스(request.FILES)를 데이터 소스와 같이 둔다. 


1
2
if request.method == "POST":
    form = Form(request.POST, request.FILES)
cs


블로그 이미지

쵸잇

,
HTML에서 이미지 삽입

1
<img style="" src="">
cs

css를 활용하여 style에서 크기 조절한다. 
src는 사진의 경로를 올린다.

1
<img style="max-width:100px;" src="{{ menu.image.url }}">
cs

최고 너비를 100px로 주었고, 이미지 경로는 메뉴 테이블에서 이미지가 저장된 곳의 url을 지정했다.


1
<img style="width:100%;" src="{{ menu.image.url }}">
cs


퍼센테이지(%)로도 사이즈 크기를 조절할 수 있다.

블로그 이미지

쵸잇

,

쿼리 연습



1) 

상황: 메뉴페이지에서 판매자(로그인 상태)가 자신이 등록한 메뉴만으로 만들어진 리스트노출된다. 

해결: 

(*메뉴 정보에 판매자 데이터 포함) 

메뉴클래스에서 판매자가 누구인지 필터하면 해당 판매자가 등록한 메뉴가 추출된다.

단, 접속한 판매자의 정보로만 구성된 메뉴리스트가 필요하다.

필터 값로그인한 판매자로 지정하여 해당 판매자의 업체 메뉴만 노출되도록 한다.


1
menu_list = Menu.objects.filter(partner=request.user.partner)
cs


블로그 이미지

쵸잇

,

데이터만 주줄이 나열되면 가독성이 떨어지고 볼품 없어 보인다.


표형식으로 깔끔하게 정리해서 보이도록 <table> 태그를 사용한다.

우리가 평소 쓰는 표가 <table>이라고 보면 된다. 대신 줄과 칸을 입력하려면 수작업이 요구된다.


<tr>은 표에서 "줄"역할을 한다. 첫번째 줄에 캐릭터 이름이 들어간 것이다.

<th>는 해당 줄의 "데이터 제목"에 해당한다. 강조 효과를 주기 위해 bold 처리가 된다.

<td>"칸"역할데이터가 표시된다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
<table class="table">
<tr>
  <th>캐릭터 이름</th>
  <td>{{ user.character.name }}</td>
</tr>
<tr>
  <th>주특기</th>
  <td>{{ user.character.type }}</td>
</tr>
<tr>
  <th>캐릭터 성별</th>
  <td>{{ user.character.gender }}</td>
</tr>
</table>
cs



완성된 형태는 아래와 같다


캐릭터 이름 

길거리파이터 

주특기

태권도

캐릭터 성별

여자



연습삼아 하나 더 만들어보자.


1
2
3
4
5
6
7
8
9
10
11
12
<table class="table">
<tr>
  <th>캐릭터 이름</th>
  <th>주특기</th>  
  <th>캐릭터 성별</th>
</tr>
<tr>
  <td>{{ user.character.name }}</td>  
  <td>{{ user.character.type }}</td>
  <td>{{ user.character.gender }}</td>
</tr>
</table>
cs


다음 테이블은 아래와 같다


캐릭터 이름

주특기

캐릭터 성별

길거리파이터

태권도

여자


블로그 이미지

쵸잇

,

html로 하나씩 입력칸을 만드는게 아니고 모델 폼을 만들어서 효율적으로 데이터를 입력하는 방법을 공부했다. 

(https://practice-a-lot.tistory.com/56)


데이터를 입력했으면 수정하는 방법도 알아보자.


입력한 데이터를 가져오는 방법쿼리를 통해데이터가 저장된 객체를 호출하여 폼에 두는 것이다.

빈 폼과의 차이점은 폼이 데이터를 보유했냐는 여부이다.



1
2
3
4
5
6
def edit_info(request):
    ctx = {}
    if request.method == "GET":
        character = Character.objects.get(user=request.user)
        form = CharacterForm(instance=character)
        ctx.update({ "form" : form })
cs



쿼리 없이 더 간단하게 처리하는 방법직접 데이터에 접근하는 것이다.


1
2
3
4
5
def edit_info(request):
    ctx = {}
    if request.method == "GET":
        form = CharacterForm(instance=request.user.character)
        ctx.update({ "form" : form })
cs


request.user.character는 이미 모델 폼을 통해 입력된 데이터가 포함되어있다. 

그러므로 굳이 쿼리를 사용해 변수에 지정하는 수고를 덜 수 있다.



데이터를 수정 후 저장할 때에도 동일한 인스턴스를 지정해둔다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def index(request):
    ctx = {}
    if request.method == "GET":
        form = CharacterForm(instance=request.user.character)
        ctx.update({ "form" : form })
    elif request.method == "POST":
        form = CharacterForm(
            request.POST,
            instance=request.user.character
        )
        if form.is_valid():
            character = form.save(commit=False)
            character.user = request.user
            character.save()
            return redirect("/character/")
        else:
            ctx.update({ "form" : form })
cs


블로그 이미지

쵸잇

,

〜に決まっている 


강한 확신이 담겨 있는 말이다. 

"분명 ~하다" "반드시 ~할 것이다" "~임에 틀림없다" "~라고 확신한다" 예문에 따라 적절한 해석이 요구된다.


最初から無理に決まっていると思うのは精神的負けている証拠だ。처음부터 무리임에 틀림없다고 생각하는 것은 정신적으로 패배한 증거다.

去年も優勝しているし、今年もうちのチームが勝つに決まっている。작년도 우승했듯이 올해도 우리 팀이 이길 거라고 확신한다.

一人で外国へ旅行するなんて、親に反対されるに決まっている。혼자서 외국으로 여행을 간다니, 부모님이 분명 반대할 게 뻔하다.

無罪になるに決まっている。무죄가 될 거라고 확신한다.

同じ値段なら、質がいいほうがたくさん売れるに決まっている。 같은 가격이라면 질이 좋은 쪽이 많이 팔릴 것임에 틀림없다.

レオナルド・ダ・ヴィンチくらい聞いたことあるに決まってるだろ。레오나르도 다 빈치 정도 들어본 적이 있음에 틀림없다.

子供にそんなお菓子を見せたらほしがるに決まっている。아이들에게 그런 과자를 보여주면 당연히 갖고싶어한다.

そんなうまい話はうそにきまっていますよ。그런 말솜는 거짓말 임에 틀림없다.


A 彼に手作りのチョコをあげようと思ってるんです。그에게 수제 초콜릿을 주려고 해요

B 手作りだったら、喜んでくれるに決まってますよ。수제 초콜릿이면 분명 기뻐해줄 거에요.


A うちの息子、来年受験なんです。우리 아들 내년에 시험이에요

B 浪人して頑張ったんだから、合格するに決まってますよ。재수해서 노력했으니깐 반드시 합격할 거에요


A 彼女、お金貸してくれるでしょうか。그녀가 돈을 빌려줄까요?

B ケチだから、貸してくれないに決まってますよ。구두쇠라서 빌려주지 않을 거에요


'외국어 > 일본어' 카테고리의 다른 글

"〜ている"는 "~하는 중이다"로만 해석되지 않는다  (0) 2018.11.24
수동형  (0) 2018.11.23
블로그 이미지

쵸잇

,

会(Huì)는 "할 줄 안다"는 뜻을 가진 조동사이다. 


"할 수 있다"의 뜻보다 더 강한 주관이 함의되어있다. 

이 말은 화자가 그동안 꾸준한 학습을 통해 얻은 능력 임을 알 수 있다.


做中国菜吗?너 중국음식 만들 줄 아니?

说汉语。나는 중국어를 말할 줄 알아


不会跳舞。그는 춤출 줄 몰라

不会做中国饭。그녀는 중국음식을 만들 줄 몰라


A 你会开车吗?너 운전할 줄 아니?

不会开车。나 운전할 줄 몰라


가능성에 대한 뜻도 가진다.


A 他会来吗?그가 올 것 같니?

B 现在九点半了,他不会来了。지금 9시가 되었어. 그는 올 것 같지 않아.


'외국어 > 중국어' 카테고리의 다른 글

중국어의 Because (因为~, 所以~)  (0) 2018.11.23
결과보어  (0) 2018.11.22
조동사 可以  (0) 2018.11.20
정도보어(상태보어)와 得  (0) 2018.11.19
기초문법 (4) - 방위사  (0) 2018.10.20
블로그 이미지

쵸잇

,
폼을 직접 만들어서 데이터를 처리한 적이 있다. 

폼의 작동 원리를 알았다면 활용도 높은 모델 폼(ModelForm)을 통해 데이터를 처리하는 방법을 알아본다.

* 모델 폼 작성요령(https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/)은 이곳에서 살펴보면 된다.


웹사이트에서 모델 폼을 통해 입력 받은 데이터를 view에서 어떻게 처리하는지는 
여기(https://docs.djangoproject.com/en/1.10/topics/forms/)에 설명이 되어있다.


나의 목표는 

1) 웹사이트에 모델 폼을 만들어서 데이터를 입력 받을 수 있도록 만들고
2) 모델 폼을 통해 입력 받은 데이터데이터베이스에 저장하도록 한다 (단, 조건에 부합한 경우저장, 아니면 재작성)


1-1) forms.py에서 Character 모델 클래스를 반영한 모델 폼 클래스를 만든다.

1
2
3
4
5
6
7
8
9
class CharacterForm(ModelForm):
     class Meta:
         model = Character
         fields = (
             'user',
             'name',
             'type',
             'gender'
         )
cs


1-2) View에서 만들어진 모델 폼호출하여 템플릿에 전달한다. 
   
1
2
3
4
5
def index(request):
    ctx = {}
    if request.method == "GET":
        form = CharacterForm()
        ctx.update({ "form" : form })
cs


GET 방식일 때, 빈 폼변수에 담아 템플릿으로 보낸다. 
폼이 비어있는 상태에서 데이터를 입력 받을 수 있도록 하기 위함이다. 
(템플릿에서 직접 폼을 만드는 번거로움이 확연히 줄었다)



2) 폼을 통해 입력 받은 데이터를 View에서 처리하여 데이터베이스에 저장한다.

 

(웹사이트에서 폼을 통해 데이터가 전송된 상황) POST 요청일때, request로부터 데이터를 가져와 폼 인스턴스를 만든다.

- *폼은 데이터가 입력된 폼 인스턴스에 대한 유효성 검사(데이터베이스 필드조건 부합)를 할 수 있다.

- Partner 클래스에 user 필드를 제외한 name, contact, address, description 필드에만 데이터를 입력 받은 상태이다.

- 인스턴스는 비어있는 필드가 있으면 데이터베이스에 저장하지 않는 경우가 발생한다.

- 아니면 저장하기 전직접 필드에 데이터를 입력하여 최종 저장시킨다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
def index(request):
    ctx = {}
    if request.method == "GET":
        form = CharacterForm()
        ctx.update({ "form" : form })
    elif request.method == "POST":
        form = CharacterForm(request.POST)
        if form.is_valid():
            character = form.save(commit=False)
            character.user = request.user
            character.save()
            return redirect("/character/")
        else:
            ctx.update({ "form" : form })
cs


2-1) 데이터를 저장하므로 POST 방식을 사용하고, 데이터를 입력 받은 폼변수로 지정한다.

 

2-2) form.is_valid()를 통해 입력된 데이터의 유효성 검사를 한다. 올바르지 않으면 재작성한다.


2-3) user 값은 직접 입력하는 것이 아니므로 별도로 채워서 최종 저장을 한다.

블로그 이미지

쵸잇

,

서비스를 이용하다가 1개 계정당 게임 캐릭터를 1개 사용할 수 있다던지하는 예를 본 적이 있을 것이다.

계정 데이터를 갖고 있는 User 테이블게임 캐릭터 정보를 갖고 있는 Charater 테이블을 만들면 아래와 같다.


User

id

username

email

password

1

streetfighter

realguy@world.com 

************** 

2

kingoffighter

toughguy@world.com 

*********** 


Character 

id

user(OneToOne)

name 

type

gender

1

1

길거리파이터

태권도

여자

2

2

싸움왕

무에타이

남자


로그인시 사용하는 계정 이름"streetfighter"인 사용자는 게임에서 "길거리파이터"라는 캐릭터 이름을 갖고 있다. 

"streetfighter"로 접속한 사람이 게임에서 사용할 캐릭터는 "길거리파이터" 뿐인 것이다.


이렇게 1대1인스턴스를 이어주는 역할을 하는 것이 OneToOneField이다.


서로 데이터가 연결되어있으니 User 테이블에서 Charater 테이블로 자유롭게 접근이 가능해진다.

OneToOneField를 사용하기 위해서는 관계를 맺을 테이블에서 새로 필드를 만들어서 자신의 테이블명을 입력하면 완성된다.


1
2
3
4
5
class Character(models.Model):
    user = models.OneToOneField(User)
    name
    type
    gender
cs


블로그 이미지

쵸잇

,