유저 부분이 생각보다 어렵다 계속해서 오류가난다 이것저것해보다가 이것저것 건드린 게 엄청난 파장을 불러왔다.... 젠장...
USERNAME_FIELD = 'email' # 로그인에 사용
REQUIRED_FIELDS = ['profilename'] #createsuperuser에 필수입력값으로 사용됨
회원가입에서 user를 만들 때 profilename을 필수 입력값으로 받지 않도록했다 ➜ 그럼 추후에 profilename을 사용하려고 할 때 기본값을 줘야하는데 그럼 user_id 를 이용해서 고유한 디폴트값을 줘야한다(첫날에 이거랑 addressfield하려다가 실패해서 음 그냥 필수 입력값으로 안했던 건데ㅜㅜ 지금 생각해보니까 이전에 기현튜터님 강의에서 봤던 랜덤으로 이름 생성해주는 그 라이브러리?
임포트했어도 됐을 것 같긴한데 이건 확실하지 않으니..) 고유하지 않으면 중복검사를 해줘야하는데 차라리 이걸 하는 게 나았을 수도 있겠다 근데 회원가입할때도 중복검사하는데 굳이 회원가입할 때 받아야하는 게 맞나??? 그럴거면 username으로 했지..? 무튼 너무 이런 세세한거에 신경 쓸 필요없이 내가 궁금한 건 이거다
models.py의 create_superuser도 결국 create_user를 이용해서 만드는데 superuser만들때의 필수항목이 회원가입할 때의 항목이랑 다를 수 있을까?
➜ 실험
➜ 인자로 받은 값들을 create_user로 instance만들 때 사용하고 is_admin만 True를 줌
➜ 위 사진에서 profilename을 빼고 createsuperuser하면 입력하라고는 안뜨는데 typeerror가 남
➜ 1의 인자값으로 profilename넣고 2의 required에도 profilename넣으면 typeerror 안남
➜ 1의 인자값으로 넣고 인스턴스엔 안넣으면 입력하라고는 뜨는데 unexpected keyword argument 안쓰는데 왜넣냐는건가??
def save(self, *args, **kwargs):
if self.pk is None:
self.profilename = self.user_id
super(Users,self).save(*args, **kwargs)
@receiver(pre_save, sender=Users)
def default_profilename(sender, instance, **kwargs):
if not instance.profilename:
instance.profilename = 'instance'+instance.user_id
## user 32 이렇게
➜ 근데 만들 때는 되게 어렵게 생각했는데 지금 지나고 보니까 그냥 db에만 넣어주면 되는데 왜 모델 생성(회원가입하는 순간!)과 동시에 기본값으로 들어갈 수 있어야한다고만 생각했을까??
=======댓글 불러오기========
const comment_text = document.getElementsByClassName("comment-text")
comment_text.innerText = product_json.comments_set[0]['comment']
console.log(comment_text.innerText)
const comment_author = document.getElementsByClassName("comment-author")
comment_author.innerText = product_json.comments_set[0]['user']
console.log(comment_author.innerText)
const comment_date = document.getElementsByClassName("comment-date")
comment_date.innerText=product_json.comments_set[0]['created_at']
console.log(comment_date.innerText)
const comment_grade = document.getElementsByClassName("comment-grade")
comment_grade.innerText=product_json.comments_set[0]['grade']
console.log(comment_grade.innerText)
이케 개고생하면서 만들어놨는데 다 하고보니까 이게 아니었던.. 어떻게하면 간단하게 다 보면서 할 수 있다고 했었는데 그게 기억이 안나서.. 콘솔 겁나 확인하면서 했던 것 같음 무튼간 댓글이 여러개면 줄줄이 이어 달리니까 인덱스 번호를 사용해야하는 거여서 forEach문 사용함
게시글 하나당 게시되는 이미지는 하나밖에 없으니까 그냥 이미지 들어가야하는 섹션 선택해서 이미지 넣어주면 됨
window.onload =
async function ProductDetail() {
//백엔드 url에서 정보가져오기
const product = await fetch(`${BACK_END_URL}/products/${product_id}/detail/`, {
headers: {
'content-type': 'application/json',
"Authorization": "Bearer " + localStorage.getItem("access")
},
method: 'GET',
})
//정보를 json값으로 변형
product_json = await product.json()
//게시글(이미지만) 불러오기
const product_image = document.getElementById("image-form")
product_image.setAttribute("src", `${BACK_END_URL}${product_json.image}`)
//댓글 불러오기
comments = product_json.comments_set
console.log(comments)
console.log(comments[0].user)
comment_frame = document.getElementById('comment-put')
comments.forEach(element => {
const comment = document.createElement('div')
comment.innerHTML =`<!-- Comments List -->
<div class="comments" id="commment">
<!-- Comment - Dummy -->
<div class="comment">
<!-- Comment Avatar -->
<div class="comment-avatar">
<img src="${BACK_END_URL}${element.user.profile}" style="height:100%">
</div>
<!-- Comment Box -->
<div class="comment-box" >
<div class="comment-text">${element.comment}</div>
<div class="comment-footer">
<div class="comment-info">
<span class="comment-author">
<a>${element.user.profilename}</a>
</span>
<span class="comment-date">${element.created_at}</span>
<span>|</span>
<span classs="comment-grade"> 점수 : ${element.grade}</span>
</div>
<div class="comment-actions" id="edit-button">
<itoken interpolation">${element.id})" class="bi bi-pencil-square"></i>
<span>/</span>
<itoken interpolation">${element.id})" class="bi bi-trash3"></i>
</div>
</div>
</div>
</div>
<!-- Comment Edit -->
<div class="comment-edit" id=edit_box>
<textarea class="input" name="comment_edit" id="comment_edit" ng-model="cmntCtrl.comment.text"
placeholder="Edit Review..." required></textarea>
<div class="edit_button">
<button type="button"token interpolation">${element.id})">add Review</button>
</div>
</div>
</div>
</div>`
comment_frame.appendChild(comment)
})
}
➜ 조회는 로드하자마자 바로 떠야하니까 onload에 넣은건데 onload가 그런 뜻이 아니고 html 문서에서 불러오고자하는 태그나 아이디 값들이 생성되기도 전에 js에 정의된 함수에서 실행돼서 발생할 수 있는 오류 상황을 피할 수 있게 해줌 사실 강의에 나왔던건데 내멋대로 해석해서 그렇다 ㅋㅋ..
무튼 js가 html하단에 있으면 상관없지만(html을 위에서부터 읽으니까) 그렇지 않은 경우에는 onload를 하는 게 정신건강에 좋을듯? 근데 그러고보니까 온로드 안에 조회기능만 넣었늰데 아무 문제가 없었던건 js가 하단에 있어서였군 ㅋㅋ....
➕ window는 웹브라우저의 객체라고 보면 되고 문서당 한번밖에 사용할 수 없다
async function addComment(){
const commentText = document.getElementById('comment_input').value;
const query = document.querySelector('input[name="rating"]:checked').value;
const response = await fetch(`${BACK_END_URL}/products/${product_id}/comment/`, {
headers: {
'content-type': 'application/json',
"Authorization": "Bearer " + localStorage.getItem("access")
},
method: 'POST',
body: JSON.stringify({
"comment": commentText,
"grade": query
})
})
if (response.status == 201) {
alert(response.data)
}
else {
alert(response.status)
}
location.reload()
}
➜ async - await
짝지어서 쓴다.
➜ js는 엥간하면 오류를 내지 않는다고 했나 자기가 대충 예상해서 이거겠지~ 하고 읽어준다더니 변수 선언할 때 var/conts/let안썼는데 그냥 알아서 잘 인식했다..