<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
</script>
<!-- accounts/profile.html -->
<form id = "follow-form">
...
</form><!-- accounts/profile.html -->
// 2. submit 이벤트가 발생하는 form 태그 선택
const formTag = document.querySelector('#follow-form')// 3. 선택한 form 태그에 이번트핸들로 할당
formTag.addEventListener("submit", function (event){
event.preventDefault()
})const formTag = document.querySelector('#follow-form')
formTag.addEventListener("submit", function (event){
event.preventDefault()
axios({
method:'post',
url:`/accounts/${}/follow` ,
})
console.log(event)
})data-* 속성
- 사용자 지정 데이터 특성을 만들어 임의의 데이터를 HTML과 DOM 사이에서 교환 할 수 있는 방법
formTag.addEventListener("submit", function (event){
event.preventDefault()
const = userID = event.currentTarget.dataset.userId
axios({
method:'post',
url:`/accounts/${userID}/follow` ,
})
})
csrf 값을 가진 input 요소를 직접 선택 후 axios에 작성하기
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value
formTag.addEventListener("submit", function (event){
event.preventDefault()
const = userID = event.currentTarget.dataset.userId
axios({
method:'post',
url:`/accounts/${userID}/follow`,
headers: {'X-CSRFToken': csrftoken,},
})
})
응답은 더이상 HTML 문서가 아닌 JSON 데이터 작성
from django.http import JsonResponse
@login_required
def follow(request, user_pk):
me = request.user
you = get_user_model().objects.get(pk=user_pk)
if me != you:
if me in you.followers.all():
you.followers.remove(me)
is_followed = False
else:
you.followers.add(me)
is_followed = True
context = {
'is_followed': is_followed,
'followings_count': you.followings.count(),
'followers_count': you.followers.count()
}
return JsonResponse(context)
return redirect('accounts:profile', you.username)
팔로우 요청 후 django 서버로 부터 받은 데이터 확인하기
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value
formTag.addEventListener("submit", function (event){
event.preventDefault()
const = userID = event.currentTarget.dataset.userId
axios({
method:'post',
url:`/accounts/${userID}/follow`,
headers: {'X-CSRFToken': csrftoken,},
}).then((response) => {
console.log(response)
console.log(response.data)
})
})
응답 데이터 is_followed에 따라 팔로우 버튼을 토글하기
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value
formTag.addEventListener("submit", function (event){
event.preventDefault()
const = userID = event.currentTarget.dataset.userId
axios({
method:'post',
url:`/accounts/${userID}/follow`,
headers: {'X-CSRFToken': csrftoken,},
}).then((response) => {
const isFollowed = response.data.is_followed
const followBtn = document.querySelector('input[type=submit]')
if (isFollowed === true){
followBtn.value = 'Unfollow'
}
else{
followBtn.value = 'Follow'
}
console.log(response)
console.log(response.data)
})
})
<div>
팔로잉 : <span id = "followings-count">{{ person.followings.all|length }}</span>/
팔로워 : <span id = "followers-count">{{ person.followers.all|length }}</span>/
</div>.then((response) => {
const followingsCountTag = document.querySelector('#followings-count')
const followersCountTag = document.querySelector('#followers-count')
})def follow(request, user_pk):
...
context = {
'is_followed' : is_followed,
'followings_count' : person.followings.count(),
'followers_count' : person.followers.count(),
}
return JsonResponse(context)
return redirect('accounts:profile', person.username)응답 데이터를 받아 각 태그의 인원수 값 변경에 적용
.then((response) => {
const followingsCountTag = document.querySelector('#followings-count')
const followersCountTag = document.querySelector('#followers-count')
followingsCountTag.textContent = response.data.followings_count
followersCountTag.textContent = response.data.followers_count
})
<article class ="article-container">
{% for article in articles %}
..
{% endfor %}
</article>이벤트 핸들러 할당
하위 요소들의 submit 이벤트를 감지하고 submit 기본 이벤트를 취소
const articleContainger = document.querySelector('.article-container')
articleContainer.addEventListener('submit', function(event){
event.preventDefault()
})
axios 작성
const articleContainger = document.querySelector('.article-container')
articleContainer.addEventListener('submit', function(event){
event.preventDefault()
axios({
method:'post',
url:`/articles/${}/likes`,
headers:{'X-CSRFToken':csrftoken,},
})
})
각 좋아요 form에 article.pk를 부여 후 HTML article.pk 값을 JavaScript에서 참조
<form data-article-id = "{{ article.pk }}">
...
</form>
const articleContainger = document.querySelector('.article-container')
articleContainer.addEventListener('submit', function(event){
event.preventDefault()
const articleId = event.target.dataset.articleId
axios({
method:'post',
url:`/articles/${}/likes`,
headers:{'X-CSRFToken':csrftoken,},
})
})
url 완성 후 요청 및 응답 확인
<form data-article-id = "{{ article.pk }}">
...
</form>
const articleContainger = document.querySelector('.article-container')
articleContainer.addEventListener('submit', function(event){
event.preventDefault()
const articleId = event.target.dataset.articleId
axios({
method:'post',
url:`/articles/${articleId}/likes`,
headers:{'X-CSRFToken':csrftoken,},
})
.then((response) => {
console.log(response)
})
.catch((error) => {
console.log(error)
})
})
좋아요 상태 여부를 JavaScript에게 전달할 데이터 작성 및 JSON 데이터 응답
form django.http import JsonResponse
@login_required
def likes(request, article_pk):
article = Article.objects.get(pk=article_pk)
if request.user in article.like_users.all():
article.like_users.remove(request.user)
is_liked = False
else:
article.like_users.add(request.user)
is_liked = True
context = {
'is_liked': is_liked,
'liked_count': article.like_users.count(),
}
return JsonResponse(context)
axios({
method:'post',
url:`/articles/${articleId}/likes`,
headers:{'X-CSRFToken':csrftoken,},
})
.then((response) => {
console.log(response)
const isLiked = response.data.is_liked
})
.catch((error) => {
console.log(error)
})axios({
method:'post',
url:`/articles/${articleId}/likes`,
headers:{'X-CSRFToken':csrftoken,},
})
.then((response) => {
console.log(response)
const isLiked = response.data.is_liked
const likeBtn = ??
})
.catch((error) => {
console.log(error)
}){% if request.user in article.like_users.all %}
<input type='submit' value = "좋아요 취소" id = "like-{{ article.pk }}">
{% else %}
<input type='submit' value = "좋아요 " id = "like-{{ article.pk }}">
{% endif %}.then((response) => {
console.log(response)
const isLiked = response.data.is_liked
const likeBtn = document.querySelector(`#like-${articleId}`)
if (isLiked === true){
likeBtn.value = '좋아요 취소'
} else{
likeBtn.value = '좋아요'
}
})
querySelectorAll()을 사용해 전체 좋아요 버튼을 선택
forEach()를 사용해 전체 좋아요 버튼을 순회하면서 진행
querySelectorAll() 선택을 위한 class 적용
{% for article in articles %}
...
<form class ="like-forms' data-article-id="{{ article.pk }}">
{% csrf_token %}
{% if request.user in article.like_users.all %}
<input type="submit" value="좋아요 취소">
{% else %}
<input type="submit" value="좋아요">
{% endif %}
</form>
<hr>
{% endfor %}
forEach()를 사용해 전체 좋아요 버튼을 순회하면서 진행
비동기 좋아요 구현한 거 캡쳐해주면 안돼요???