Today I Learn 220506
์ค๋์ AJAXํต์ ์ ์ด์ฉํด ์๋ฒ์์ JSON๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ ๋น๋๊ธฐ๋ก ํ๋ฉด์ ๊ตฌ์ฑํ๋ ๊ณผ์ ๋ฅผ ์งํํ์๋ค. ์ธ์ ๋ ๊ทธ๋ ๋ฏ ์ค๋ฅ๋ฅผ ๋ง๋ฌ๋ค. ์์ง axios๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์ต์ํ์ง ์์์ ํด๋จผ์๋ฌ๊ฐ ๋ง์ด ๋ฌ์๋ค.
<์ ์ ํ๋ก์ฐ ๊ธฐ๋ฅ>
์ด๋ ค์ ๋ ์
์ ์ ํ๋ก์ฐ ๊ธฐ๋ฅ์ ๊ตฌํํ๋๋ฐ url์ ์ฐฉ๊ฐํด์ accounts/pk/follow/๊ฐ ๋์ด์ผ ํ๋๋ฐ, accounts/username/follow๋ก ๋ง๋ค์๋ค. ๊ทธ๋์ 404 ์ค๋ฅ๋ฅผ ๋ง๋์ 1์๊ฐ ๋๊ฒ ๊ตฌ๊ธ๋ง ํ๋ค๊ฐ network ๋ณด๋๋ฒ์ ๊ณต๋ถํ๋ค...^.ใ ๊ทธ ์ค ๋์ค์ ๊ธฐ์ตํ๊ธฐ ์ํด ๋จ๊ฒจ๋๋ ๋ธ๋ก๊ทธ ๋งํฌ(https://github.com/Lagom92/TIL/blob/master/web/400%20%EC%97%90%EB%9F%AC%20%ED%95%B4%EA%B2%B0%20%ED%95%98%EA%B8%B0.md )
๊ทธ๋์ ๊ฒฝ๋ก์ ๋ฃ์ด์ฃผ๋ ๊ฐ์ด ๋ฌธ์ ๋ผ๋ ์ ์ ์๊ฒ๋์ด **profile.html**์ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํํ๋ค.
{% extends 'base.html' %}
{% block content %}
<h1>{{ person.username }}์ ํ๋กํ ํ์ด์ง</h1>
{% with followings=person.followings.all followers=person.followers.all %}
<div>
<div id="follow-count">
ํ๋ก์ : {{ followings|length }} / ํ๋ก์ : {{ followers|length }}
</div>
{% if request.user != person %}
<div>
<form id="follow-form" data-user-id="{{ person.pk }}" action="{% url 'accounts:follow' person.pk %}" method="POST">
{% csrf_token %}
{% if request.user in followers %}
<button id="followBtn">์ธํ๋ก์ฐ</button>
{% else %}
<button id="followBtn">ํ๋ก์ฐ</button>
{% endif %}
</form>
</div>
{% endif %}
</div>
{% endwith %}
{% endblock %}
{% block script %}
<script>
const form = document.querySelector('#follow-form')
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value
form.addEventListener('submit', function (event) {
event.preventDefault()
const userId = event.target.dataset.userId
axios({
method: 'post',
url: `http://127.0.0.1:8000/accounts/${userId}/follow/`,
headers: {'X-CSRFToken': csrftoken},
})
.then(response => {
const isFollowed = response.data.is_followed
const followersCount = response.data.followers_count
const followingsCount = response.data.followings_count
const followBtn = document.querySelector('#followBtn')
const followCountDiv = document.querySelector('#follow-count')
if (isFollowed === true) {
followBtn.value = '์ธํ๋ก์ฐ'
} else {
followBtn.value = 'ํ๋ก์ฐ'
}
followCountDiv.innerText = `ํ๋ก์ ์: ${followingsCount} / ํ๋ก์ ์: ${followersCount}`
})
.catch(response => {
console.log(response);
})
})
</script>
{% endblock script %}
<๋ฆฌ๋ทฐ ์ข์์ ๊ธฐ๋ฅ ๊ตฌํ>
์ด๋ ค์ ๋ ์
์์ ์ ์ ํ๋ก์ฐ ๊ธฐ๋ฅ๊ณผ ๊ฐ์ด 404 ์ค๋ฅ๋ฅผ ๋ง๋ฌ๋ค...
์ค๋์๊ฐ ์์์ ์ค๋ฅ๋ฅผ ๋ง๋ ์๊ฐ์ด ๋ง์ด ํ๋ฅธ ์ํ๋ผ ๋ง์์ด ๊ธํด์ ธ์ ์ฐฌ์ฐฌํ ๋ณด์ง ๋ชปํ๋๋ฐ ๋ค์ ๋ณด๋ viewํจ์์์ context์ count๋ฅผ 'is_count' ๋ผ๊ณ ์ง์ ํด์ฃผ๊ณ
views.py
@require_POST
def like(request, review_pk):
if request.user.is_authenticated:
review = get_object_or_404(Review, pk=review_pk)
user = request.user
if review.like_users.filter(pk=user.pk).exists():
review.like_users.remove(user)
is_liked = False
else:
review.like_users.add(user)
is_liked = True
context = {
'is_liked':is_liked,
'is_count':review.like_users.conunt()
}
return JsonResponse(context)
# return redirect('community:index')
return redirect('accounts:login')
index.html
{% extends 'base.html' %}
{% block content %}
<h1>Community</h1>
<hr>
{% for review in reviews %}
<p>์์ฑ์ : <a href="{% url 'accounts:profile' review.user.username %}">{{ review.user }}</a></p>
<p>๊ธ ๋ฒํธ: {{ review.pk }}</p>
<p>๊ธ ์ ๋ชฉ: {{ review.title }}</p>
<p>์ํ ์ ๋ชฉ: {{ review.movie_title }}</p>
<p>๊ธ ๋ด์ฉ: {{ review.content }}</p>
<form class="like-form" action="{% url 'community:like' review.pk %}" method="POST" data-review-id="{{ review.pk }}" class="d-inline">
{% csrf_token %}
{% if user in review.like_users.all %}
<button id="like-{{ review.pk }}">์ข์์ ์ทจ์</button>
{% else %}
<button id="like-{{ review.pk }}">์ข์์</button>
{% endif %}
</form>
<p id="like-count-{{ review.pk }}">{{ review.like_users.all|length }} ๋ช
์ด ์ด ๊ธ์ ์ข์ํฉ๋๋ค.</p>
<a href="{% url 'community:detail' review.pk %}">[detail]</a>
<hr>
{% endfor %}
{% endblock %}
{% block script %}
<script>
const forms = document.querySelectorAll('.like-form')
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value
forms.forEach(form => {
form.addEventListener('submit', function (event) {
event.preventDefault()
const reviewId = event.target.dataset.reviewId
axios({
method: 'post',
url: `http://127.0.0.1:8000/community/${reviewId}/like/`,
headers: { 'X-CSRFToken': csrftoken },
})
.then(response => {
const likeCount = response.data.is_count
const isLiked = response.data.is_liked
const likeButton = document.querySelector(`#like-${reviewId}`)
const likeCountText = document.querySelector(`#like-count-${reviewId}`)
if (isLiked === true) {
likeButton.innerText = '์ข์์ ์ทจ์'
} else {
likeButton.innerText = '์ข์์'
}
likeCountText.innerText = `${likeCount} ๋ช
์ด ์ด ๊ธ์ ์ข์ํฉ๋๋ค.`
})
})
})
</script>
{% endblock script %}
index.html์์๋ response.data.like_count๋ผ๊ณ ์ ์ด์์๋ค.
๊ทธ๋์ response.data.is_count๋ก ๋ฐ๊พธ์ด ์ฃผ์๋ค!
๊ทธ๋ฆฌ๊ณ axios url ๋งํฌ๋ฅผ community๋ก ์์ ๊ณ ๋ค๋ฅธ๊ฑธ ์ ์ด์ฃผ์ด ๊ฒฝ๋ก๋๋ฌธ์ ๊ณ์ ์ค๋ฅ๊ฐ ๋๊ฑฐ์๋ค.
ํ๋ก์ ํธ๋ฅผ ๋๋ด๊ณ ๋๋์
์ค๋๋ ํด๋จผ ์๋ฌ๊ฐ ๊ฐ๋ํ ํ๋ฃจ์๋๋ฐ... ๊ทธ๋๋ ์ค๋ฅ๋ฅผ ํ๋์ฉ ๊ณ ์ณ๋๊ฐ๋ฉด์ ๊ตฌ๊ธ๋ง์ ํตํด ๋ฐฐ์๊ฐ๋๊ฑฐ ๊ฐ๋ค. axios์ ๊ธฐ๋ณธ ํ๊ณผ ํ๋ฆ์ ๋ํด ์ฃผ๋ง์ ์ ๋ฆฌ๋ฅผ ํ ๋ฒ ๋ ํด์ผ๊ฒ ๋ค.
'๐๐จ๐๐๐ฒ ๐ ๐๐๐๐ซ๐ง' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๐๐จ๐๐๐ฒ ๐ ๐๐๐๐ซ๐ง 2022.05.10.ํ (0) | 2022.05.10 |
---|---|
๐๐จ๐๐๐ฒ ๐ ๐๐๐๐ซ๐ง 2022.05.09.์ (0) | 2022.05.09 |
๐๐จ๐๐๐ฒ ๐ ๐๐๐๐ซ๐ง 2022.05.03.ํ (0) | 2022.05.03 |
๐๐จ๐๐๐ฒ ๐ ๐๐๐๐ซ๐ง 2022.05.02.์ (0) | 2022.05.02 |
๐๐จ๐๐๐ฒ ๐ ๐๐๐๐ซ๐ง 2022.04.28.๋ชฉ (0) | 2022.05.02 |
๋๊ธ