code review - sim jun bo
salad lab onboarding - [TodoList]
- Frontend - angular
- Backend - django
1. Frontend
- / (home)
- / singup
- / login
- / todo
- / popup
2. Backend
- / api
- / user
- / todo
1.1 home - '/ '
- img
- 기능
- 페이지 이동
#1
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.less'],
})
export class HomeComponent implements OnInit {
constructor(private router: Router) {}
signup() {
this.router.navigate(['/signup']);
}
gologin() {
this.router.navigate(['/login']);
}
ngOnInit(): void {}
}
#2
const routes: Routes = [
{ path: 'todo', component: TodoComponent },
{ path: 'home', component: HomeComponent },
{ path: 'signup', component: SignupComponent },
{ path: 'popup', component: PopupComponent },
{ path: 'login', component: LoginComponent },
{ path: '', pathMatch: 'full', component: HomeComponent },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
1.2 singup - ' /singup '
- img
- 기능
- 회원가입
- 페이지 이동 - 'home' 의 페이지이동기능과 동일한 방법
#1
import { Component, OnInit } from '@angular/core';
import { ApiService } from '../service/api.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.less'],
providers: [ApiService],
})
export class SignupComponent implements OnInit {
username = '';
password = '';
newusername = '';
newpassword = '';
SignupResult = '';
constructor(private ApiServices: ApiService, private router: Router) {}
// 데이터 잘 받는지 확인하는 작업
SignupInputText() {
console.log('username :', this.username);
console.log('password :', this.password);
}
// 데이터 바깥으로 보내기 위한 함수
PostInputText() {
this.ApiServices.create<any>('user/signup', {
username: this.username,
password: this.password,
}).subscribe(
(json) => {
console.log('result: ', json);
this.SignupResult = json['result'];
if (this.SignupResult == '0') {
console.log('back값 확인', this.SignupResult);
alert('회원가입이 완료되었습니다. 감사합니다.');
this.gologin();
} else if (this.SignupResult == '1') {
alert('이미 사용중인 아이디입니다.');
} else if (this.SignupResult == '2') {
alert('빈 값을 채워주세요');
} else console.log('미상 에러');
// 값 저장하기 (회원가입 여부 성공 or 실패)
},
(error) => {
console.log('error');
console.log(this.username);
}
);
}
PostInputText() 함수
PostInputText() {
this.ApiServices.create<any>('user/signup', {
username: this.username,
password: this.password,
}).subscribe(
(json) => {
console.log('result: ', json);
this.SignupResult = json['result'];
if (this.SignupResult == '0') {
console.log('back값 확인', this.SignupResult);
alert('회원가입이 완료되었습니다. 감사합니다.');
this.gologin();
} else if (this.SignupResult == '1') {
alert('이미 사용중인 아이디입니다.');
} else if (this.SignupResult == '2') {
alert('빈 값을 채워주세요');
} else console.log('미상 에러');
// 값 저장하기 (회원가입 여부 성공 or 실패)
},
(error) => {
console.log('error');
console.log(this.username);
}
);
}
this.ApiServices.create<any>('user/singup' ,{
username:this.username,
password:this.password,
}
ApiServices.create - post 기능
create<'any'>
username , password 라는 key로 서버에게
this.username , this.password를 보낸다
).subscribe(
(json) => {
console.log('result: ', json);
this.SignupResult = json['result'];
if (this.SignupResult == '0') {
console.log('back값 확인', this.SignupResult);
alert('회원가입이 완료되었습니다. 감사합니다.');
this.gologin();
} else if (this.SignupResult == '1') {
alert('이미 사용중인 아이디입니다.');
} else if (this.SignupResult == '2') {
alert('빈 값을 채워주세요');
} else console.log('미상 에러');
// 값 저장하기 (회원가입 여부 성공 or 실패)
},
(error) => {
console.log('error');
console.log(this.username);
}
);
subscribe() - 서버로부터 응답받기
subscribe((json) => {...}, (error) => {...})
-> json 응답이 오면 json {}안에 해당되는 코드 실행
-> json 응답이 없을경우 , error {} 안에 코드 실행
this.SignupResult = json["result"]
-> SignupResult 에 담긴 서버의 응답에 따라 경고문 or login 창으로 이동
#2
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class ApiService {
constructor(private http: HttpClient) {}
public BASE_URL = 'http://localhost:8000/api/';
get<T>(endPoint: string, params: {} = {}, headers: {} = {}): Observable<T> {
const options = this.makeOption(params, headers);
return this.http.get<T>(`${this.BASE_URL}${endPoint}`, options);
}
create<T>(
endPoint: string,
payload: {} = {},
params: {} = {},
headers: {} = {}
): Observable<T> {
// const options = {
// params: params,
// headers: headers,
// };
return this.http.post<T>(`${this.BASE_URL}${endPoint}`, payload, params);
}
update<T>(
endPoint: string,
payload: {} = {},
params: {} = {},
headers: {} = {}
): Observable<T> {
return this.http.put<T>(`${this.BASE_URL}${endPoint}`, payload, params);
}
delete<T>(
endPoint: string,
params: {} = {},
headers: {} = {}
): Observable<T> {
return this.http.delete<T>(`${this.BASE_URL}${endPoint}`, params);
}
makeOption(params: {} = {}, headers: {} = {}) {
return {
headers: headers,
observe: 'body' as 'body',
params: params,
reportProgress: false,
responseType: 'json' as 'json',
withCredentials: true,
};
}
}
1.3 login - ' / login '
- img
- 기능
- 로그인
- session - localstorage 정보 저장
- 페이지 이동 - 'home' 의 페이지이동기능과 동일한 방법
#1
import { Component, OnInit } from '@angular/core';
import { ApiService } from '../service/api.service';
import { Router } from '@angular/router';
// 로그인에서 세션 사용
import { SessionService } from '../service/session.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.less'],
providers: [ApiService],
})
export class LoginComponent implements OnInit {
loginusername = '';
Userid = '';
loginpassword = '';
loginresult = false;
key: string = '';
constructor(
private ApiServices: ApiService,
private router: Router,
private session: SessionService
) {}
loginInputText() {
this.ApiServices.create<any>('user/login', {
loginusernames: this.loginusername,
loginpasswords: this.loginpassword,
}).subscribe(
(json) => {
console.log('result: ', json);
this.loginresult = json['result'];
this.Userid = json['resUserid'];
if (this.loginresult == true) {
//로그인 성공할시 session사용하여 localstorage에 저장되게 하자
this.session.setInfo(this.Userid);
this.GoMainPage();
console.log('success_login', this.loginresult);
} else {
alert('아이디 또는 패스워드를 확인하세요.');
console.log('fail_login', this.loginresult);
// this.LoginError();
}
},
(error) => {
console.log('error');
}
);
}
GoMainPage() {
this.router.navigate(['/todo']);
}
ngOnInit(): void {}
}
LoginInputText() 함수
loginInputText() {
this.ApiServices.create<any>('user/login', {
loginusernames: this.loginusername,
loginpasswords: this.loginpassword,
}).subscribe(
(json) => {
console.log('result: ', json);
this.loginresult = json['result'];
this.Userid = json['resUserid'];
if (this.loginresult == true) {
//로그인 성공할시 session사용하여 localstorage에 저장되게 하자
this.session.setInfo(this.Userid);
this.GoMainPage();
console.log('success_login', this.loginresult);
} else {
alert('아이디 또는 패스워드를 확인하세요.');
console.log('fail_login', this.loginresult);
// this.LoginError();
}
},
(error) => {
console.log('error');
}
);
}
.subscribe(
(json) => {
console.log('result: ', json);
this.loginresult = json['result'];
this.Userid = json['resUserid'];
if (this.loginresult == true) {
//로그인 성공할시 session사용하여 localstorage에 저장되게 하자
this.session.setInfo(this.Userid);
this.GoMainPage();
console.log('success_login', this.loginresult);
} else {
alert('아이디 또는 패스워드를 확인하세요.');
console.log('fail_login', this.loginresult);
-> (2) this.GoMainPage();
-> user의 고유 id를 localstorage에 저장
-> 나중에 위 값을 통해 로그인 된 user에게 맞는 각각의 todolist를 불러온다.
#2
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class SessionService {
constructor() {}
setInfo(userid: string) {
localStorage.setItem('USERNAME_ID', userid);
}
getInfo() {
return localStorage.getItem('USERNAME_ID');
}
logOut() {
localStorage.removeItem('USERNAME_ID');
}
}
setInfo() 함수
setInfo(userid: string) {
localStorage.setItem('USERNAME_ID', userid);
}
getInfo() 함수
getInfo() {
return localStorage.getItem('USERNAME_ID');
}
logOut() 함수
logOut() {
localStorage.removeItem('USERNAME_ID');
}
1.4 todo - ' / todo '
- img(1) - list 생성 전
- img(2) - list 생성 후
- 기능
- 로그인 된 user에 맞는 list 불러오기
- 상태처리 - status에 따른 list 위치 변경
- duedate버튼 클릭시 , 정렬 상태 전환
- modify 버튼 클릭시 , 화면 전환 (updatemode)
- create 버튼 클릭시 , 화면 전환 (createmode) - 단순 페이지 이동 , 생략
- delete 버튼 클릭시 , 해당 list 삭제
- logout 버튼 클릭시 , storage정보 제거 후 로그아웃
#1
import { Component, OnInit } from '@angular/core';
import { ApiService } from '../service/api.service';
import { Router } from '@angular/router';
import { SessionService } from '../service/session.service';
@Component({
selector: 'app-todo',
templateUrl: './todo.component.html',
styleUrls: ['./todo.component.less'],
providers: [ApiService],
})
export class TodoComponent implements OnInit {
todomaining = '';
todomaindone = '';
todoidpk = '';
todoidstatus = '';
// todo 상태 결정변수s
originalstatus = true;
// popup상태 결정변수s
createpopup = false;
updatepopup = true;
// popup 에게 넘겨줄 현재 todo데이터
transPopupStatus = false;
transPopupTitle = '';
transPopupContent = '';
transPopupDuedate = '';
transPopupCreate = '';
transPopupUpdate = '';
// popup 넘겨줄때 데이터가공
processPopupduedate = '';
processPopupduedate2 = '';
processPopupcreate = '';
processPopupcreate2 = '';
processPopupupdate = '';
processPopupupdate2 = '';
// session 사용할 변수
useridtd = this.session.getInfo();
// duedate 정렬 버튼 변수
duedatebtnon = '1';
// button result (무한변경에 사용)
resultduedatebtn1 = 0;
resultduedatebtn2 = 0;
constructor(
private apiService: ApiService,
private router: Router,
private session: SessionService
) {}
// todo 생성 팝업으로 이동
gotodopopup() {
this.router.navigate(['/popup']);
}
// todolist db에 정보 가져오는 함수 (GET)
getToDoPlan() {
this.apiService
.create<any>('todo/sendtodo', {
UserIdtd: this.useridtd,
duedatebtn: 0,
})
.subscribe(
(json) => {
console.log('result_todo_data:', json);
this.todomaining = json['tdmaining'];
console.log('tdmding', this.todomaining);
},
(error) => {
console.log('error');
}
);
}
getToDoDone() {
this.apiService
.create<any>('todo/sendtodo2', {
UserIdtd: this.useridtd,
duedatebtn: 0,
})
.subscribe(
(json) => {
console.log('result_todo_data:', json);
this.todomaindone = json['tdmaindone'];
console.log('tdmddone', this.todomaindone);
},
(error) => {
console.log('error');
}
);
}
// due date -> 이른 순 또는 늦은순에 따라 정렬하기 || default -> 이른순 , 클릭시 반대값으로 정렬
lineupDueDatePlan() {
this.apiService
.create<any>('todo/sendtodo', {
UserIdtd: this.useridtd,
duedatebtn: 1,
})
.subscribe(
(json) => {
console.log('successduedate');
this.todomaining = json['tdmaining'];
},
(error) => {
console.log('duedateerror');
}
);
}
lineupDueDateDone() {
this.apiService
.create<any>('todo/sendtodo2', {
UserIdtd: this.useridtd,
duedatebtn: 1,
})
.subscribe(
(json) => {
console.log('successduedate');
this.todomaindone = json['tdmaindone'];
},
(error) => {
console.log('duedateerror');
}
);
}
// btn의 값이 짝수인지 홀수인지에 따라 다른 정렬함수 호출
resultplanduedate() {
this.resultduedatebtn1 += 1;
if (this.resultduedatebtn1 % 2 == 0) {
this.getToDoPlan();
} else {
this.lineupDueDatePlan();
}
console.log(this.resultduedatebtn1);
}
resultdoneduedate() {
this.resultduedatebtn2 += 1;
if (this.resultduedatebtn2 % 2 == 0) {
this.getToDoDone();
} else {
this.lineupDueDateDone();
}
console.log(this.resultduedatebtn2);
}
// id 인자값으로 html 파일의 (tdmd[0]을 받는다)
deleteToDo(id: string) {
console.log(id);
this.todoidpk = id;
this.apiService
.create<any>('todo/delete', {
todopkid: this.todoidpk,
})
.subscribe(
(json) => {
console.log('gooddelete');
this.getToDoPlan();
this.getToDoDone();
},
(error) => {
console.log('error');
}
);
}
// modifybutton을 클릭하였을때 ,
// 1.popup창으로 전환,
modifyToDo(id: string) {
console.log('modify', id);
this.todoidpk = id;
this.originalstatus = false;
this.postToDoPopup();
}
// status 버튼 check 시 status값 변환
checkstatus(id: string) {
this.todoidstatus = id;
console.log('checkstatus', id);
this.apiService
.update<any>('todo/statusmodify', {
statusid: this.todoidstatus,
})
.subscribe(
(json) => {
console.log('status success');
location.reload();
},
(error) => {
console.log('error');
}
);
}
//페이지 로딩될떄마다 db에서 todo data불러오기
backtodo() {
this.originalstatus = true;
}
//todo 에서 modify버튼 클릭시 해당 todoid에 맞는 값 back에 전송
postToDoPopup() {
this.apiService
.create<any>('todo/sendtodopopup', {
tdpopupid: this.todoidpk,
})
.subscribe(
(json) => {
console.log('popupresult', json);
this.transPopupStatus = json['tdcurrentstatus'];
this.transPopupTitle = json['tdcurrenttitle'];
this.transPopupContent = json['tdcurrentcontent'];
this.transPopupDuedate = json['tdcurrentduedate'];
this.transPopupCreate = json['tdcurrentcreate'];
this.transPopupUpdate = json['tdcurrentupdate'];
// 한번에 데이터 가공 - duedate
this.processPopupduedate =
this.transPopupDuedate.substring(0, 10) +
' ' +
this.transPopupDuedate.substring(11, 16);
// 두개의 변수를 이용한 데이터 가공 - createdate, updatedate
this.processPopupcreate = this.transPopupCreate.substring(0, 10);
this.processPopupcreate2 = this.transPopupCreate.substring(11, 16);
this.processPopupupdate = this.transPopupUpdate.substring(0, 10);
this.processPopupupdate2 = this.transPopupUpdate.substring(11, 16);
console.log('success', this.transPopupStatus);
},
(error) => {
console.log('error');
}
);
}
// Log Out -> session 정보값 remove , 이동하기 -> 홈으로
logout() {
this.session.logOut();
this.router.navigate(['']);
}
ngOnInit(): void {
this.getToDoPlan();
this.getToDoDone();
}
}
useridtd = this.session.getInfo();
.
.
.
getToDoPlan() {
this.apiService
.create<any>('todo/sendtodo', {
UserIdtd: this.useridtd,
duedatebtn: 0,
})
'/todo'url에 올때마다 gettododb() 함수 작동
ngOnInit() -> "라이프 사이클 " - 초기화기능
#. 유사 -> constructor()
ngOnInit(): void {
this.getToDoPlan();
this.getToDoDone();
}
plan / done에 대한 함수 따로 작성
-> 따로 함수를 작성한 이유중 가장 큰 것은
duedate btn에 따라 정렬될때 plan 일때와 done일때 따로 작용해야 되기 때문이다.
그렇기에 함수를 따로 작성하였고 백엔드에서도 api를 세분화 시켰다.
getToDoPlan() {
this.apiService
.create<any>('todo/sendtodo', {
UserIdtd: this.useridtd,
duedatebtn: 0,
})
.subscribe(
(json) => {
console.log('result_todo_data:', json);
this.todomaining = json['tdmaining'];
console.log('tdmding', this.todomaining);
},
(error) => {
console.log('error');
}
);
}
getToDoDone() {
this.apiService
.create<any>('todo/sendtodo2', {
UserIdtd: this.useridtd,
duedatebtn: 0,
})
.subscribe(
(json) => {
console.log('result_todo_data:', json);
this.todomaindone = json['tdmaindone'];
console.log('tdmddone', this.todomaindone);
},
(error) => {
console.log('error');
}
);
}
img 1. - plan mode
img 2. - Done mode
checkstatus(id: string) {
this.todoidstatus = id;
console.log('checkstatus', id);
this.apiService
.update<any>('todo/statusmodify', {
statusid: this.todoidstatus,
})
.subscribe(
(json) => {
console.log('status success');
location.reload();
},
(error) => {
console.log('error');
}
);
}
<img (click)="checkstatus(tdmding[0])" src="assets/image/circle2.png"
style="width:36px; margin-left:33px; margin-top:10px; cursor: pointer;">
status img : 클릭시 , checkstatus()함수에 고유 todoid를 인자로 넣어 서버에 전달
resultplanduedate() / this.resultduedatebtn = '?'
- 짝 -> getToDoPlan()
- 홀 -> lineupDueDatePlan()
img . modify
<ng-container *ngIf="!originalstatus">
<!-- 앞에 것이 자식 컴포넌트 변수 , 뒤에 것이 부모 컴포넌트 변수 -->
<app-popup (originalstate)="backtodo()" [todoid]="todoidpk" [createmode]="createpopup" [updatemode]="updatepopup"
[todocurrentstatus]="transPopupStatus" [todocurrenttitle]="transPopupTitle"
[todocurrentcontent]="transPopupContent" [todocurrentduedate]="processPopupduedate"
[todocurrentduedate2]="processPopupduedate2" [todocurrentcreate]="processPopupcreate"
[todocurrentcreate2]="processPopupcreate2" [todocurrentupdate]="processPopupupdate"
[todocurrentupdate2]="processPopupupdate2"></app-popup>
</ng-container>
<ng-container *ngIf="originalstatus">
.
.
.
@Input 데코레이터 사용
부모(todo)로부터 자식(popup)이 써야되는 데이터가 있기때문에
부모 html에서 쓰임을 작성 ,
앞이 자식 , 뒤가 부모
#. ex)
[todoid]="todoidpk"
img . delete
deleteToDo(id: string) {
console.log(id);
this.todoidpk = id;
this.apiService
.create<any>('todo/delete', {
todopkid: this.todoidpk,
})
.subscribe(
(json) => {
console.log('gooddelete');
this.getToDoPlan();
this.getToDoDone();
},
(error) => {
console.log('error');
}
);
}
img . logout
logout() {
this.session.logOut();
this.router.navigate(['']);
}
logOut() {
localStorage.removeItem('USERNAME_ID');
}
session.service.ts / logOut() 을 사용한 것
removeItem() 으로 key값 삭제
this.router.navigate([''])
: session제거 후 홈으로 이동
1.5 popup - ' / popup '
- img(1) - createmode
- img(2) - updatemode
- 기능
- createmode - 새로운 list 에 맞는 값 서버로 전달
- createmode - material : datetimepicker
- updatemode - list에 맞는 값 placeholder에 지정해주기
- updatemode - list에 변경된 값 서버로 전달
#1
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ApiService } from '../service/api.service';
import { Router } from '@angular/router';
import { TodoComponent } from '../todo/todo.component';
import { SessionService } from '../service/session.service';
@Component({
selector: 'app-popup',
templateUrl: './popup.component.html',
styleUrls: ['./popup.component.less'],
})
export class PopupComponent implements OnInit {
@Input() todoid = '';
// popup 역할 - 1.create , 2. update || default 는 createmode
@Input() createmode = true;
@Input() updatemode = false;
// popup - modify모드일때 현재값 불러오기 - 부모(todo)에게 전달받아
@Input() todocurrentstatus = false;
@Input() todocurrenttitle = '';
@Input() todocurrentcontent = '';
@Input() todocurrentduedate = '';
@Input() todocurrentduedate2 = '';
@Input() todocurrentcreate = '';
@Input() todocurrentcreate2 = '';
@Input() todocurrentupdate = '';
@Input() todocurrentupdate2 = '';
// /todo 기본으로 돌아가기 위한 , 자식에서 부모로 상태값 넘기기 위한 변수
@Output() originalstate = new EventEmitter<boolean>();
// create mode 일때 변수
todostatus = false;
todotitle = '';
todocontent = '';
tododuedate = '';
// modify mode 일때 변수
todomdstatus = false;
todomdtitle = '';
todomdcontent = '';
todomdduedate = '';
// session 에 저장되어있는 user_id를 사용해서 todocreate 할때 기입할 변수
userid = '';
// 수정버튼눌렀을때 사용 변수
todopopupdata = '';
data = Date();
constructor(
private ApiServices: ApiService,
private router: Router,
private session: SessionService
) {}
// tododata check 함수 -> 확인 ok
checktododata() {
console.log('status:', this.todostatus);
console.log('title:', this.todotitle);
console.log('content:', this.todocontent);
console.log('duedata:', this.tododuedate);
}
// popup창 취소 버튼 구현
popupcancle() {
this.router.navigate(['/todo']);
}
backtoorigin(value: boolean) {
this.originalstate.emit(value);
}
// todo db에 data 보내기
PostToDoData() {
console.log('session result', this.session.getInfo());
console.log('duedate 실험', this.tododuedate);
this.ApiServices.create<any>('todo/create', {
userids: this.session.getInfo(),
tdstatus: this.todostatus,
tdtitle: this.todotitle,
tdcontent: this.todocontent,
tdduedate: this.tododuedate,
}).subscribe(
(json) => {
console.log('good');
this.router.navigate(['/todo']);
},
(error) => {
console.log('error');
alert('필수 항목을 입력해주세요.');
}
);
}
// todo 해당 id에 맞는 db 가져오기
// todo db 수정하기
updateToDoData() {
var updatetime = new Date();
this.ApiServices.update<any>('todo/modify', {
tdmdid: this.todoid,
tdmdstatus: this.todomdstatus,
tdmdtitle: this.todomdtitle,
tdmdcontent: this.todomdcontent,
tdmdduedate: this.todomdduedate,
}).subscribe(
(json) => {
console.log('success');
console.log('업데이트시간', updatetime);
this.backtoorigin(true);
// reload방법으로 , 수정시 새로고침하여 db값 가져오기
location.reload();
},
(error) => {
console.log('error');
}
);
}
// create창에서 status상태 변경 btn 구현
statusbtncreate() {
if (this.todostatus == false) {
this.todostatus = true;
} else {
this.todostatus = false;
}
}
statusbtnupdate() {
if (this.todomdstatus == false) {
this.todomdstatus = true;
} else {
this.todomdstatus = false;
}
}
// calendar 구현
ngOnInit(): void {}
}
// popup 역할 - 1.create , 2. update || default 는 createmode
@Input() createmode = true;
@Input() updatemode = false;
<ng-container *ngIf="updatemode">
<!-- 부모 자식 데이터 전달 테스트 -->
<div class="realpopups2">
<div class="infoboxs2">
<div class="titlebox2">
<input class="Titletext2" [(ngModel)]="todomdtitle" type="text" placeholder={{todocurrenttitle}} />
</div>
.
.
.
<!-- new -material -date&time -->
<div class="datetime">
<mat-form-field>
<input matInput type="datetime-local" [(ngModel)]="tododuedate">>
</mat-form-field>
</div>
<!-- /new -material -date&time -->
popup.component는 todo.module.ts에 상속되어있다.
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
<div class="duedatebox2">
<div>
<p style="margin:20px; font-size: 20px;">Due Date : </p>
</div>
<div class="duedateinputbox2">
<input class="DueDatetext2" [(ngModel)]="todomdduedate" type="text" placeholder={{todocurrentduedate}} />
</div>
</div>
'/api'
settings.py
urls.py
'/user'
views.py
urls.py
models.py
apps.py
'/todo'
views.py
urls.py
models.py
apps.py
'/api'
'/api/settings.py'
#1. settings.py
#mainpoint1
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user',
'todo',
'corsheaders',
]
#mainpoint2
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
#mainpoint3
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
#mainpoint4
CORS_ORIGIN_WHITELIST = ['http://127.0.0.1:4200' ,'http://localhost:4200']
CORS_ALLOW_CREDENTIALS = True
#mainpoint5
APPEND_SLASH=False
*csrf :웹 어플리케이션 취약점 중 하나로 인터넷 사용자(희생자)가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게 만드는 공격
CORS : Cross Origin Resource Sharing
CORS 문제는 다른 도메인의 서버로부터 요청이 들어왔을 때, 헤더에 접근을 허락하는 내용이 없으면 발생한다
접근 허락을 위해(django-cors-headers 설치)
1.
INSTALLED_APPS = [
...
'corsheaders',
...
]
2.
# Corsmiddleware가 Commonmiddleware보다 위에 설정
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
3.
CORS_ORIGIN_WHITELIST = ['http://127.0.0.1:4200' ,'http://localhost:4200']
'/api'
'/api/urls.py'
#2. urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('api/', include([
path('todo/', include('todo.urls')),
path('admin/', admin.site.urls),
path('user/', include('user.urls') )
])),
]
'/user'
user table 관리 및 user 관련 함수 생성
'/user/models.py'
#1. user/models.py
class UserSignup(models.Model):
id = models.IntegerField(primary_key=True)
user_name = models.CharField(max_length=50)
password = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now_add=True)
'/user/views.py'
views.signup
views.login
#1. user/views.py
# 1. 회원가입
# user/signup
def signup(request):
if request.method == 'POST':
# POST처리 성공여부 확인
print("signup_success")
# try:
#어느 곳에 데이터가 들어가있는지 확인(body or POST)
print('body',request.body)
print('post',request.POST)
#프론트에서 데이터 받아서 저장
SignupPayload = json.loads(request.body)
print("payload" , SignupPayload)
username = SignupPayload["username"]
password = SignupPayload["password"]
print("test", username , password)
# ---회원삭제---
# deletes = UserSignup.objects.all()
# deletess = deletes.delete()
# 1. 회원가입시 user_name 중복체크
# 1.1 현재 table의 username 모두 가져오기
usernames = UserSignup.objects.all().values_list('user_name' , flat = True)
print("현재 usrname:", usernames)
# ---프론트에게 던져줄 값---
# -> 0,1 에서 null값 처리를 위해 경우를 세분화 (성공,중복에러,null에러)
success = {
'result': '0'
}
DuplicationFail = {
'result' : '1'
}
NullFail ={
'result' : '2'
}
# print("프론트값전달" , success, DuplicationFail )
# 1.2.1 -> null값은 불통처리
if (username == '') or (password == ''):
return JsonResponse(NullFail)
# 1.2 중복체크 통과 -> 저장 , 불통 -> 경고메세지
for i in usernames:
if i == username:
# 불통 -> 경고메세지 실행 및 http 오류 처리
print("---error: 사용자 정보가 중복으로 존재합니다---")
return JsonResponse(DuplicationFail )
# 통과 -> 저장 및 확인메세지 출력
new_user = UserSignup.objects.create(user_name= username , password =password )
print("---success: 저장이 되었습니다---")
return JsonResponse(success )
# 예외처리
# except Exception as e:
# print("error", e)
# 2. 로그인
# user/login
# 먼저, username부터 확인하고 성공시 다음 orm 진행
# 통과 할시, password 값 확인 후 로그인 처리
def login(request):
if request.method == 'POST':
print("로그인 통신")
#0. front에서 사용자가 기입한 username과 password값
LoginPayload = json.loads(request.body)
print("front data: ", LoginPayload)
LoginUsername = LoginPayload["loginusernames"]
print("사용자입력id : " ,LoginUsername)
LoginPassword = LoginPayload["loginpasswords"]
print("사용자입력pw : " ,LoginPassword)
#1.DB username 확인
UsernameSet = UserSignup.objects.all().values_list("user_name" , flat = True)
print(UsernameSet)
# 1단계, username 일치하는지 확인
loginusernamefail = {
"result" : False
}
x =0
for i in UsernameSet:
if i == LoginUsername:
x += 1
print("x", x)
else:
print("bad")
if x ==0:
print("username fail _ firstfail")
return JsonResponse(loginusernamefail)
#2.DB에서 해당 user -> password 확인
Passwordreal = UserSignup.objects.filter(user_name = LoginUsername).values_list("password", flat= True)
print("아사람의 패스워드: " ,Passwordreal[0])
#2-2 -> session이용하기 위한 해당 username에 대한 userid값 넘겨주기
Userids = UserSignup.objects.filter(user_name = LoginUsername).values("id")
print("USERID:" , Userids)
# 2단계, username 일치 통과한 유저는 password 일치하는지 확인
loginsuccess = {
"result" : True,
"resUserid" : Userids[0]["id"]
}
loginpasswordfail = {
"result" : False
}
# 수정 -> passwordset -> passwordreal(하나의 값)
if Passwordreal[0] == LoginPassword:
return JsonResponse(loginsuccess )
return JsonResponse(loginpasswordfail)
회원가입
- 사용자가 입력한 username과 password를 받는다
- 중복 username이 생기면 안되기에, userdb에 있는 username값을 전부 가져온다.
- 회원가입 성공여부를 결정한다.
- 3.1 사용자가 username 또는 password중 빈값으로 기입한것이 있는지 확인한다.
- 3.2 사용자가 기입한 username이 기존 db에 있는지 확인한다.
- 3.3 회원가입 성공여부를 결정한다.
SignupPayload = json.loads(request.body)
username = SignupPayload["username"]
password = SignupPayload["password"]
- request.body 로 프론트의 데이터가 담겨온다
- request.post에는 데이터가 담겨지지 않았다.
- json 은 javascript object notation으로 키-값으로 이루어진 object이다.
- json 타입과 python은 1:1 매칭되며 아래와 같다.
- dictionary형태로 역변환 시켰기에 ,
username = SignupPayload["username"] 으로 값 저장한다.
usernameset = UserSignup.objects.all().values_list('user_name' , flat = True)
- orm 사용
- UserSignup (table) 에서 모든 값중 'user_name' 필드값만 가지고 온다.
- values()는 Dict를 반환하고, values_list()는 Tuple을 반환
- username 사용 가능 확인을 위해선 , 리스트 형태가 필요하다고 판단
- values_list( , flat = True) -> list형태 반환
NullFail ={
'result' : '2'
}
if (username == '') or (password == ''):
return JsonResponse(NullFail)
- ' ' 가 빈값처리된 것.
- 둘중 하나라도 빈값이면 오류 데이터 전송
success = {
'result': '0'
}
DuplicationFail = {
'result' : '1'
}
for i in usernameset:
if i == username:
# 불통 -> 경고메세지 실행 및 http 오류 처리
print("---error: 사용자 정보가 중복으로 존재합니다---")
return JsonResponse(DuplicationFail )
# 통과 -> 저장 및 확인메세지 출력
new_user = UserSignup.objects.create(user_name= username , password =password )
print("---success: 저장이 되었습니다---")
return JsonResponse(success )
- .create 사용하여 데이터 저장
- UserSignup.objects.create(user_name = username ,..)
로그인
- 사용자가 입력한 username(id)와 password를 받는다
- 로그인의 성공여부를 결정한다.
- 2.1 사용자가 입력한 username이 실제db에 존재하는지 확인
- 2.2 2.1통과시 사용자가 입력한 password가 db에 존재하는 입력한 username의 password와 일치하는지 확인
- 로그인 성공시 session에 저장될 사용자의 고유 id를 프론트에 전달해준다.
-> 회원가입 로직과 동일
먼저 , username이 일치하는지 확인하고! 다음 단계로 이동, 없을 경우 그 상태에서 바로 fail return 해주기
윗 단계가 통과 될시! , 실제 db 해당 password불러오고 일치하는지 확인
UsernameSet = UserSignup.objects.all().values_list("user_name" , flat = True)
print(UsernameSet)
# 1단계, username 일치하는지 확인
loginusernamefail = {
"result" : False
}
x =0
for i in UsernameSet:
if i == LoginUsername:
x += 1
print("x", x)
else:
print("bad")
if x ==0:
print("username fail _ firstfail")
return JsonResponse(loginusernamefail)
loginsuccess = {
"result" : True,
"resUserid" : Userids[0]["id"]
}
loginpasswordfail = {
"result" : False
}
# 수정 -> passwordset -> passwordreal(하나의 값)
if Passwordreal[0] == LoginPassword:
return JsonResponse(loginsuccess )
return JsonResponse(loginpasswordfail)
```
Userids = UserSignup.objects.filter(user_name = LoginUsername).values("id")
loginsuccess = {
"result" : True,
"resUserid" : Userids[0]["id"]
}
- filter사용
- 이번엔 values사용
- values를 사용했기에 , Userids[0]["id"] 로 값 저장
'/todo'
todo table 관리 및 todo 관련 함수 생성
'/todo/models.py'
#1. todo/models.py
class TodoModel(models.Model):
id = models.IntegerField(primary_key=True)
user_id = models.IntegerField(null=True)
status = models.BooleanField(null=False)
title = models.CharField(max_length=64,null=False)
content = models.CharField(max_length=300)
due_date = models.DateTimeField(null=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
'/todo/views.py'
views.sendtododb
views.sendtododb2
views.sendtodopopup
views.todocreate
views.tododelete
views.todomodify
views.statusmodify
#1. todo/views.py
# todo/sendtodo -> plan에 대한
def sendtododb(request):
if request.method == 'POST':
useridPayload = json.loads(request.body)
ThisUserId = useridPayload['UserIdtd']
print("get_success_sendtododata")
#due_date정렬을 여기서 관리를 해줘야할거같다.
#button - on -> order_by().reverse() 사용
#button - off -> order_by() 만 사용
button = useridPayload['duedatebtn']
print("duedate" , button)
# 정렬에 -> order_by() , reverse() 사용
if button == 0:
TodoDBing = list(TodoModel.objects.order_by('due_date').filter(user_id=ThisUserId, status = False).values_list('id','status','title','content','due_date' ))
else :
TodoDBing = list(TodoModel.objects.order_by('due_date').reverse().filter(user_id=ThisUserId, status = False).values_list('id','status','title','content','due_date' ))
print("현재 진행중: ", TodoDBing)
data = {
'tdmaining' : TodoDBing,
}
return JsonResponse(data)
# todo/sendtodo2 -> done에 대한
def sendtododb2(request):
if request.method == 'POST':
useridPayload = json.loads(request.body)
ThisUserId = useridPayload['UserIdtd']
print("get_success_sendtododata")
#due_date정렬을 여기서 관리를 해줘야할거같다.
#button - on -> order_by().reverse() 사용
#button - off -> order_by() 만 사용
button = useridPayload['duedatebtn']
print("duedate" , button)
if button == 0:
TodoDBdone = list(TodoModel.objects.order_by('due_date').filter(user_id=ThisUserId, status = True).values_list('id','status','title','content','due_date' ))
else :
TodoDBdone = list(TodoModel.objects.order_by('due_date').reverse().filter(user_id=ThisUserId, status = True).values_list('id','status','title','content','due_date' ))
print("완료 : ", TodoDBdone)
data = {
'tdmaindone' : TodoDBdone,
}
return JsonResponse(data)
# todo/sendtodopopup
# todopopup - 해당 id 값에 맞는 값들 전송
def sendtodopopup(request):
if request.method == 'POST':
print("get_success_sendpopup")
# front에서 보낸 todo id 값
popupidPayload = json.loads(request.body)
tdid = popupidPayload['tdpopupid']
print("front에서 넘겨준 tododid: " , tdid)
# todoDB 에서 usetdid와 동일한 값의 행 추출
tddata = TodoModel.objects.filter(id = tdid).values()
# front에 넘겨줄 data
todocurrentdata = {
'tdcurrentstatus' : tddata[0]['status'] ,
'tdcurrenttitle' : tddata[0]['title'],
'tdcurrentcontent' : tddata[0]['content'],
'tdcurrentduedate' : tddata[0]['due_date'],
'tdcurrentcreate' : tddata[0]['created_at'],
'tdcurrentupdate' : tddata[0]['updated_at'],
}
print("추출된 해당 데이터:" , todocurrentdata)
return JsonResponse(todocurrentdata)
# 1. 할일 생성
# todo/create
def todocreate(request):
if request.method == 'POST':
print("post_success_create")
# 프론트에서 todo data 받아서 변수에 저장
TodoPayload = json.loads(request.body)
print("payload" , TodoPayload)
tduserid = TodoPayload['userids']
tdstatus = TodoPayload["tdstatus"]
tdtitle = TodoPayload["tdtitle"]
tdcontent = TodoPayload["tdcontent"]
tdduedate = TodoPayload["tdduedate"]
print("todo data: " , tduserid, tdstatus , tdtitle , tdcontent, tdduedate )
# todo data저장
new_todo = TodoModel.objects.create(user_id = tduserid ,status = tdstatus , title =tdtitle , content = tdcontent, due_date=tdduedate )
print("새로운 todo저장되었습니다.")
successdata = {
'result' : True
}
return JsonResponse(successdata)
# 2. 할일 삭제
# todo/delete
def tododelete(request):
if request.method == 'POST':
# 삭제할 todo pk id받기
TodoDeletePayload = json.loads(request.body)
TodoPkId = TodoDeletePayload['todopkid']
print('id:', TodoPkId)
# 행 삭제하기
deletetodo = TodoModel.objects.filter(id = TodoPkId)
print("삭제될 행 추출" , deletetodo)
GoDeleteToDo = deletetodo.delete()
print("post_success_delete")
data = {
'success' : True
}
return JsonResponse(data)
# 3. 할일 수정
# todo/modify
def todomodify(request):
if request.method == 'PUT':
print("post_success_modify")
modifyPayload = json.loads(request.body)
print("modifypayload : ", modifyPayload)
# front에서 수정된 값을 비교하고 바뀌었을 경우 바뀐 값 저장 ,
# 수정된 값이 null일 경우 -> 원래의 값으로 저장
# 1. 해당 id에 맞는 현재 값 들
currentToDo = TodoModel.objects.filter(id = modifyPayload['tdmdid']).values()
# 2. 각 컬럼 (4가지 - status , title , content , due_date ) 비교
newstatus = modifyPayload['tdmdstatus']
newtitle = modifyPayload['tdmdtitle']
newcontent = ''
newduedate = ''
# 2 - * 수정하기 버튼 클릭 시 그 시점으로 업데이트 처리하여 수정된 날짜 나오게 하기 위한 것
newupdate= datetime.now()
# 2-1 -> status 비교 -> 수정 ok
if modifyPayload['tdmdstatus'] == '':
newstatus = currentToDo[0]['status']
print("status is same")
else :
print( "status is modify")
# 2-2 -> title 비교 -> 수정 ok
if modifyPayload['tdmdtitle'] == '':
newtitle = currentToDo[0]['title']
print("title is same")
else :
print( "title is modify")
# 2-3 -> content 비교 -> 수정 ok
if modifyPayload['tdmdcontent'] :
newcontent = modifyPayload['tdmdcontent']
else :
newcontent = currentToDo[0]['content']
print("content is same")
# 2-4 -> due date 비교 -> 수정 ok
if modifyPayload['tdmdduedate'] == '':
newduedate = currentToDo[0]['due_date']
print("duedate is same")
else :
newduedate = modifyPayload['tdmdduedate']
# 새로운 값으로 대체
print("--------------------------------------------------------------------")
print('새로운 값: ' , newstatus, newtitle,newcontent,newduedate )
modify_todo= TodoModel.objects.filter(id = modifyPayload['tdmdid']).update(status =newstatus , title =newtitle , content =newcontent , due_date=newduedate , updated_at = newupdate)
print("변경완료되었습니다 -> " , modify_todo)
data = {
'resultmodify' : 0
}
return JsonResponse(data)
# 4. 상태 수정
# todo/statusmodify
def statusmodify(request):
if request.method == "PUT":
statusmodifyPayload = json.loads(request.body)
statusmodifycurrent = TodoModel.objects.filter(id = statusmodifyPayload['statusid']).values('status')
print("status 추출" ,statusmodifycurrent)
# 클릭시 반대로 바꿔서 상태저장하기
currentstatus = statusmodifycurrent[0]
print("현상태값" ,currentstatus)
newstatusTrue = True
newstatusFalse = False
data = {
"result" : 1
}
# status 현재 상태 체크 후 반대상태로 업데이트 한 후 프론트로 응답하기
if statusmodifycurrent[0]['status'] == False:
updatestatus = TodoModel.objects.filter(id = statusmodifyPayload['statusid']).update(status = newstatusTrue)
print("완료상태로 변경완료")
return JsonResponse(data)
else :
print("not")
if statusmodifycurrent[0]['status'] == True:
updatestatus = TodoModel.objects.filter(id = statusmodifyPayload['statusid']).update(status = newstatusFalse)
print("미완료 상태로 변경완료")
return JsonResponse(data)
else :
print("not")
전체 list중 'status'가 'false'인 list를 보내주는 역할
- 추가적으로, duedate 버튼에 따라 해당 list의 정렬상태를 관리
# todo/sendtodo -> plan에 대한
def sendtododb(request):
if request.method == 'POST':
useridPayload = json.loads(request.body)
ThisUserId = useridPayload['UserIdtd']
print("get_success_sendtododata")
#due_date정렬을 여기서 관리를 해줘야할거같다.
#button - on -> order_by().reverse() 사용
#button - off -> order_by() 만 사용
button = useridPayload['duedatebtn']
print("duedate" , button)
# 정렬에 -> order_by() , reverse() 사용
if button == 0:
TodoDBing = list(TodoModel.objects.order_by('due_date').filter(user_id=ThisUserId, status = False).values_list('id','status','title','content','due_date' ))
else :
TodoDBing = list(TodoModel.objects.order_by('due_date').reverse().filter(user_id=ThisUserId, status = False).values_list('id','status','title','content','due_date' ))
print("현재 진행중: ", TodoDBing)
data = {
'tdmaining' : TodoDBing,
}
return JsonResponse(data)
TodoDBing = list(TodoModel.objects.order_by('due_date').filter(user_id=ThisUserId, status = False).values_list('id','status','title','content','due_date' ))
- list() - 프론트에서 ngFor사용하여 화면에 보여줄거라, list형태로 가공
- order_by('due_date') - default 는 지정해준 컬럼에 대한 오름차순 (기본값은 duedate에 따른 오름차순 정렬이기에 order_by사용)
- filter(user_id =ThisUserId , status= False )
- 로그인 된 사용자에 맞는 값, 그 중에서도 위 api에 맞게 status가 false인 값만 추출되도록
- values_list() - 필요한 컬럼만 추출
- main 페이지에서 modify버튼을 클릭시, updatemode_popup창이 실행된다. 이때 해당 tdlist에 맞는 status,title,content와 같은 필요한 값들을 보내주는 역할을 한다.
# todo/sendtodopopup
# todopopup - 해당 id 값에 맞는 값들 전송
def sendtodopopup(request):
if request.method == 'POST':
print("get_success_sendpopup")
# front에서 보낸 todo id 값
popupidPayload = json.loads(request.body)
tdid = popupidPayload['tdpopupid']
print("front에서 넘겨준 tododid: " , tdid)
# todoDB 에서 usetdid와 동일한 값의 행 추출
tddata = TodoModel.objects.filter(id = tdid).values()
# front에 넘겨줄 data
todocurrentdata = {
'tdcurrentstatus' : tddata[0]['status'] ,
'tdcurrenttitle' : tddata[0]['title'],
'tdcurrentcontent' : tddata[0]['content'],
'tdcurrentduedate' : tddata[0]['due_date'],
'tdcurrentcreate' : tddata[0]['created_at'],
'tdcurrentupdate' : tddata[0]['updated_at'],
}
print("추출된 해당 데이터:" , todocurrentdata)
return JsonResponse(todocurrentdata)
- 새로운 todolist를 사용자가 작성하면 그 값들을 받아와 todo_db에 insert시켜주는 역할을 한다.
# 1. 할일 생성
# todo/create
def todocreate(request):
if request.method == 'POST':
print("post_success_create")
# 프론트에서 todo data 받아서 변수에 저장
TodoPayload = json.loads(request.body)
print("payload" , TodoPayload)
tduserid = TodoPayload['userids']
tdstatus = TodoPayload["tdstatus"]
tdtitle = TodoPayload["tdtitle"]
tdcontent = TodoPayload["tdcontent"]
tdduedate = TodoPayload["tdduedate"]
print("todo data: " , tduserid, tdstatus , tdtitle , tdcontent, tdduedate )
# todo data저장
new_todo = TodoModel.objects.create(user_id = tduserid ,status = tdstatus , title =tdtitle , content = tdcontent, due_date=tdduedate )
print("새로운 todo저장되었습니다.")
successdata = {
'result' : True
}
return JsonResponse(suc
new_todo = TodoModel.objects.create(user_id = tduserid ,status = tdstatus , title =tdtitle , content = tdcontent, due_date=tdduedate )
- create() - 새로운 data를 db에 생성하고 삽입한다.
- 사용자가 삭제하고자 하는 list의 삭제 버튼을 클릭하였을때, 해당 list를 tododb에서 삭제시키는 역할을 한다.
# 2. 할일 삭제
# todo/delete
def tododelete(request):
if request.method == 'POST':
# 삭제할 todo pk id받기
TodoDeletePayload = json.loads(request.body)
TodoPkId = TodoDeletePayload['todopkid']
print('id:', TodoPkId)
# 행 삭제하기
deletetodo = TodoModel.objects.filter(id = TodoPkId)
print("삭제될 행 추출" , deletetodo)
GoDeleteToDo = deletetodo.delete()
print("post_success_delete")
data = {
'success' : True
}
return JsonResponse(data)
- 사용자가 수정하고 싶은 list를 수정한 후 수정버튼을 누르면, 해당 list가 수정된 값으로 tododb에 업데이트 되서 저장되게 한다.
# 3. 할일 수정
# todo/modify
def todomodify(request):
if request.method == 'PUT':
print("post_success_modify")
modifyPayload = json.loads(request.body)
print("modifypayload : ", modifyPayload)
# front에서 수정된 값을 비교하고 바뀌었을 경우 바뀐 값 저장 ,
# 수정된 값이 null일 경우 -> 원래의 값으로 저장
# 1. 해당 id에 맞는 현재 값 들
currentToDo = TodoModel.objects.filter(id = modifyPayload['tdmdid']).values()
# 2. 각 컬럼 (4가지 - status , title , content , due_date ) 비교
newstatus = modifyPayload['tdmdstatus']
newtitle = modifyPayload['tdmdtitle']
newcontent = ''
newduedate = ''
# 2 - * 수정하기 버튼 클릭 시 그 시점으로 업데이트 처리하여 수정된 날짜 나오게 하기 위한 것
newupdate= datetime.now()
# 2-1 -> status 비교 -> 수정 ok
if modifyPayload['tdmdstatus'] == '':
newstatus = currentToDo[0]['status']
print("status is modify")
else :
print( "status is modify")
# 2-2 -> title 비교 -> 수정 ok
if modifyPayload['tdmdtitle'] == '':
newtitle = currentToDo[0]['title']
print("title is same")
else :
print( "title is modify")
# 2-3 -> content 비교 -> 수정 ok ,
# 값이 있으면 if x :
if modifyPayload['tdmdcontent'] :
newcontent = modifyPayload['tdmdcontent']
print('컨텐트 ',modifyPayload['tdmdcontent'] )
else :
newcontent = currentToDo[0]['content']
print("content is same")
# 2-4 -> due date 비교 -> 수정 ok
if modifyPayload['tdmdduedate'] == '':
newduedate = currentToDo[0]['due_date']
print("duedate is same")
else :
newduedate = modifyPayload['tdmdduedate']
# 새로운 값으로 대체
print("--------------------------------------------------------------------")
print('새로운 값: ' , newstatus, newtitle,newcontent,newduedate )
modify_todo= TodoModel.objects.filter(id = modifyPayload['tdmdid']).update(status =newstatus , title =newtitle , content =newcontent , due_date=newduedate , updated_at = newupdate)
print("변경완료되었습니다 -> " , modify_todo)
data = {
'resultmodify' : 0
}
return JsonResponse(data)
- main 화면에서 status가 false인 현재진행중인 섹션과 status가 true인 완료 섹션의 list들 중에서 사용자가 status버튼을 클릭하여 상태값을 바꿀떄 status값이 바뀐상태로 tododb에 저장되게 한다
# 4. 상태 수정
# todo/statusmodify
def statusmodify(request):
if request.method == "PUT":
statusmodifyPayload = json.loads(request.body)
statusmodifycurrent = TodoModel.objects.filter(id = statusmodifyPayload['statusid']).values('status')
print("status 추출" ,statusmodifycurrent)
# 클릭시 반대로 바꿔서 상태저장하기
currentstatus = statusmodifycurrent[0]
print("현상태값" ,currentstatus)
newstatusTrue = True
newstatusFalse = False
data = {
"result" : 1
}
# status 현재 상태 체크 후 반대상태로 업데이트 한 후 프론트로 응답하기
if statusmodifycurrent[0]['status'] == False:
updatestatus = TodoModel.objects.filter(id = statusmodifyPayload['statusid']).update(status = newstatusTrue)
print("완료상태로 변경완료")
return JsonResponse(data)
else :
print("not")
if statusmodifycurrent[0]['status'] == True:
updatestatus = TodoModel.objects.filter(id = statusmodifyPayload['statusid']).update(status = newstatusFalse)
print("미완료 상태로 변경완료")
return JsonResponse(data)
else :
print("not")