๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • What would life be If we had no courage to attemp anything?
๐“๐จ๐๐š๐ฒ ๐ˆ ๐‹๐ž๐š๐ซ๐ง

๐“๐จ๐๐š๐ฒ ๐ˆ ๐‹๐ž๐š๐ซ๐ง 2022.05.06.๊ธˆ

by DevIseo 2022. 5. 6.

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์˜ ๊ธฐ๋ณธ ํ‹€๊ณผ ํ๋ฆ„์— ๋Œ€ํ•ด ์ฃผ๋ง์— ์ •๋ฆฌ๋ฅผ ํ•œ ๋ฒˆ ๋” ํ•ด์•ผ๊ฒ ๋‹ค.

๋Œ“๊ธ€