input 태그 안에 value 속성을 사용하면 된다.


1
<input type="name" name="name" value="{{ user.partner.name }}">
cs


속성 값으로는 이미 데이터베이스에 저장된 데이터를 지정한다.


블로그 이미지

쵸잇

,

Grid system웹페이지12개의 열로 나누어서 활용하게 만든다.



1
2
3
4
5
6
7
8
9
10
11
12
<div class="row">
  <div class="col-sm-6 col-sm-offset-3">
    <div class="row">
      {% for partner in partner_list %}
      <div class="col-sm-4">
        <h4>{{ partner.name }}</h4>
        <div>{{ partner.address }}</div>
      </div>
      {% endfor %}
    </div>
  </div>
</div>
cs



<div class="col-sm-6 col-sm-offset-3">에서

col-sm-offset-3은 3개 열을 상쇄시켜서 가운데 정렬을 할 수 있도록 한다.

양옆 3칸비워두고 가운데 6칸에서 데이터를 매핑하게 된다.



<div class="col-sm-4">는

12개 칸 중4칸을 사용해서 이름과 주소를 매핑하는데,

for문을 통해 순차적으로 다른 데이터도 매핑되므로 4칸씩 자리를 차지하게 된다.

3번 연속으로 4칸을 차지하면 12칸이 되므로 그 다음 데이터는 아랫줄로 이어서 출력하게 된다.

블로그 이미지

쵸잇

,

먼저 쿼리를 통해 가져온 객체를 변수에 담고,

이를 delete() 메소드를 사용하여, 리다이렉트만 해주면 간단히 끝난다.



1
2
3
4
def menu_delete(request, menu_id):
    menu = Menu.objects.get(id=menu_id)
    menu.delete()
    return redirect("/partner/menu/")
cs


블로그 이미지

쵸잇

,

목적은 

데이터를 입력할 때의 폼과 그 데이터를 수정할 때의 폼동일하게 쓰인다는 점에서,

1개의 폼 사용을 유지하고자 템플릿을 서로 만들지 않고 같은 템플릿을 사용하게 한다.


조건 2가지

1) url 경로와 view 함수는 서로 달라야한다. (기능이 다르므로)

2) 서로 다른 기능을 하는 것임을 표시할 수 있도록 조건에 따라 다르게 화면에 보여야한다.



1-1) url과 view 함수를 따로 만든다.


서로 다른 경로를 가지고, 서로 다른 기능을 유지하기에 고유의 url와 view 함수를 지닌다.



1-2) 매핑할 템플릿 페이지를 동일하게 지정한다.


(데이터 추가하는 add 함수)


1
2
3
4
def add(request):
    ctx = {}
    (생략)
    return render(request, "add.html", ctx)
cs


(데이터 수정하는 edit 함수)


1
2
3
4
def edit(request):
    ctx = { "replacement" : "수정" }
    (생략)
    return render(request, "add.html", ctx)
cs



2) 기존 템플릿에서 조건문을 추가한다.


(데이터 추가 텍스트만 보이는 템플릿)


1
2
3
4
5
6
추가하기
<form enctype="multipart/form-data" method="post" action="">
  {% csrf_token %}
  {{ form.as_p }}
  <button class="btn btn-default btn-block">추가</button>
</form>
cs



(조건문을 넣어서 사용하는 함수에 따라 다르게 보이는 템플릿)


1
2
3
4
5
6
{% if replacement %}{{ replacement }}{% else %}추가{% endif %}하기
<form enctype="multipart/form-data" method="post" action="">
  {% csrf_token %}
  {{ form.as_p }}
  <button class="btn btn-default btn-block">{% if replacement %}{{ replacement }}{% else %}추가{% endif %}</button>
</form>
cs


edit 함수를 매핑하는 url로 접속시 replacement호출하도록 조건을 내세워 "추가하기" 텍스트를 "수정하기" 형태로 바꾼다.

블로그 이미지

쵸잇

,

깃에서 제외할 파일을 지정할 때는 .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


블로그 이미지

쵸잇

,