티스토리 뷰

Dev/Python

Django API 연동하기 - 1. 준비운동

데어이즈 2018. 6. 1. 15:50

우리는 지난시간 Django Restframework를 이용해 만든 게시판 타입을 저장하고 노출하는 board-type이라는 API를 만들고 연동하기 위해 CORS 셋팅까지 마쳤다. 이제 Angular를 통해서 CRUD 전체 기능을 구현하고 조금 더 복잡한 기능을 구현하기 위한 발판을 만들어볼거다.

오늘은 별말 없이 그냥 코드만 줄줄이 올려야지.



app.component.html

<h2>추가하기</h2>
<table class="table">
    <thead>
        <tr>
            <th>Type</th>
            <th>Description</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <input type="text" [(ngModel)]="newType" />
            </td>
            <td>
                <input type="text" [(ngModel)]="newDescription" />
            </td>
            <td class="tac">
                <div>
                    <button (click)="onCreateClick()">추가</button>
                </div>
            </td>
        </tr>
    </tbody>
</table>

<h2>게시판 타입 목록</h2>
<table class="table">
    <thead>
        <tr>
            <th>ID</th>
            <th>Type</th>
            <th>Description</th>
            <th>Created</th>
            <th>Updated</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let item of boardTypeList">
            <td>
                <span>{{item.id}}</span>
            </td>
            <td>
                <span *ngIf="!item.isEdit">{{item.type}}</span>
                <input *ngIf="item.isEdit" type="text" [(ngModel)]="item.type" />
            </td>
            <td>
                <span *ngIf="!item.isEdit">{{item.description}}</span>
                <input *ngIf="item.isEdit" type="text" [(ngModel)]="item.description" />
            </td>
            <td>
                <span>{{item.created_at| date: 'yyyy-MM-dd HH:mm:ss'}}</span>
            </td>
            <td>
                <span>{{item.updated_at| date: 'yyyy-MM-dd HH:mm:ss'}}</span>
            </td>
            <td class="tac">
                <div *ngIf="!item.isEdit">
                    <button (click)="onEditClick(item)">수정</button>
                    <button (click)="onDeleteClick(item)">삭제</button>
                </div>
                <div *ngIf="item.isEdit">
                    <button (click)="onSaveClick(item)">저장</button>
                    <button (click)="onEditCancel(item)">취소</button>
                </div>
            </td>
        </tr>
    </tbody>
</table>


app.component.css

.table {
    border-collapse: collapse;
    border-spacing: 0;
    table-layout: fixed;
    width: 100%;
}

.table th, .table td {
    font-size: 14px;
    font-weight: normal;
    border: 1px solid #CCC;
    padding: 5px;
    box-sizing: border-box;
}

.table th {
    background-color: #EEE;
}

.table td.tac {
    text-align: center;
}

.table td span {
    line-height: 22px;
}

.table td input {
    width: 100%;
    font-size: 14px;
    line-height: 16px;
    box-sizing: border-box;
}


app.component.ts

import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { Http, RequestOptionsArgs, RequestMethod, Headers } from '@angular/http';
import { Observable } from 'rxjs';
import { HttpParamsOptions } from '@angular/common/http/src/params';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

    public newType:string = "";
    public newDescription:string = "";
    public boardTypeList:Array<any> = [];

    private http:HttpClient;

    constructor( http:HttpClient ){
        this.http = http;
    }

    public ngOnInit():void {
        this.getBoardTypeList();
    }

    private request( url:string, method:string, params:HttpParams ):Observable<arraybuffer> {
        let headers:HttpHeaders = new HttpHeaders({
            'Accept': 'application/json, */*'
            , "Content-Type": "application/json"
        });

        let body:any = {}

        if( params && (
                method == "POST" ||
                method == "PATCH" ||
                method == "PUT"
            ) ){
            console.log( params.keys() );

            for (let index in params.keys()) {
                let key:string = params.keys()[index];
                body[key] = params.get(key);
            }
        }

        let options:any = {
            headers: headers
            , params: params
            , body: body
        };

        return this.http.request(method, url, options);
    }

    /**
     *  게시판 타입 목록 가져오기
     */
    private getBoardTypeList():void {
        this.request('http://localhost:8000/board-type/', 'GET', null)
        .subscribe((data)=>{
            let result:any = data;
            
            for( let i = 0; i < result.length; i++ ){
                let item:any = result[i];
                item.isEdit = false;
            }

            this.boardTypeList = result;
        }, (error) =>{
            alert("게시판 타입 목록을 가져오던 도중 오류가 발생하였습니다.");
        }, () =>{
            console.log( "complete" );
        });
    }

    /**
     *  게시판 타입 생성하기
     */
    public onCreateClick():void {
        if( this.newType == "" ){
            alert("타입을 입력해주세요.");
            return;
        }

        if( this.newDescription == "" ){
            alert("설명을 입력해주세요.");
            return;
        }

        let params:HttpParamsOptions = {
            fromObject: {
                type: this.newType
                , description: this.newDescription
            }
        };

        this.request('http://localhost:8000/board-type/', 'POST', new HttpParams(params))
        .subscribe( (data) =>{
            this.newType = "";
            this.newDescription = "";

            this.getBoardTypeList();
        }, (error) =>{
            alert("게시판 타입을 생성하던 도중 오류가 발생하였습니다.");
            console.log( error );
        }, () =>{
            console.log( "complete");
        });
    }

    /**
     * 아이템 수정모드 진입하기
     * @param item 수정할 아이템
     */
    public onEditClick( item:any ):void {
        item.isEdit = true;
    }

    /**
     * 아이템 삭제하기
     * @param item 
     */
    public onDeleteClick( item:any ):void {
        if( confirm("정말 삭제하시겠습니까?") ){
            this.request('http://localhost:8000/board-type/' + item.id + "/", 'DELETE', null)
            .subscribe( (data) =>{
                this.getBoardTypeList();
            }, (error) =>{
                alert("게시판 타입을 삭제하던 도중 오류가 발생하였습니다.");
                console.log( error );
            }, () =>{
                console.log( "complete");
            });
        }
    }

    /**
     * 아이템 수정 취소하기
     * @param item
     */
    public onEditCancel( item:any ):void {
        item.isEdit = false;
    }

    /**
     * 아이템 수정 내용 저장하기
     * @param item 
     */
    public onSaveClick( item:any ):void {
        let params:HttpParamsOptions = {
            fromObject: {
                type: item.type
                , description: item.description
            }
        };

        this.request('http://localhost:8000/board-type/' + item.id + "/", 'PUT', new HttpParams(params))
        .subscribe( (data) =>{
            this.getBoardTypeList();
        }, (error) =>{
            alert("게시판 타입을 수정하던 도중 오류가 발생하였습니다.");
            console.log( error );
        }, () =>{
            console.log( "complete");
        });
    }
}


자, 위와 같이 코딩을 하면 아래와 같은 게시판 타입의 목록을 불러오고 새로 작성도 하며 수정, 삭제도 할 수 있는 웹 페이지가 만들어지게 됩니다.



자 이제 여기에 페이징과 검색을 추가하고 곧 로그인과 게시판을 작성할 준비를 하도록 하자.

Python 카테고리에서 프론트엔드 작업만 줄줄이 써놓긴 했는데 어쩌겠어. 이걸 해야 다음 단계를 진행 할 수 있는데.


그럼 담시간에 또 만나자. 안녕!


댓글
댓글쓰기 폼