포스트 수정 페이지에 태그 입력란 추가하기

Posted on 2021-08-25 by GKSRUDTN99
Django로 웹사이트 만들기 장고

테스트 코드 작성하기

# tests.py
    def test_update_post(self):
        update_post_url = f'/blog/update_post/{self.post_003.pk}/'

        # 로그인하지 않은 경우
        response = self.client.get(update_post_url)
        self.assertNotEqual(response.status_code, 200)

        # 로그인은 했지만 작성자가 아닌 경우
        self.assertNotEqual(self.post_003.author, self.user_trump)
        self.client.login(
            username=self.user_trump.username,
            password='somepassword'
        )
        response = self.client.get(update_post_url)
        self.assertEqual(response.status_code, 403)

        # 작성자(obama)가 접근하는 경우
        self.client.login(
            username=self.post_003.author.username,
            password='somepassword'
        )
        response = self.client.get(update_post_url)
        self.assertEqual(response.status_code, 200)
        soup = BeautifulSoup(response.content, 'html.parser')

        self.assertEqual('Edit Post - Blog', soup.title.text)
        main_area = soup.find('div', id='main-area')
        self.assertIn('Edit Post', main_area.text)

        tag_str_input = main_area.find('input', id='id_tags_str')
        self.assertTrue(tag_str_input)
        self.assertIn('파이썬 공부; python', tag_str_input.attrs['value'])

        response = self.client.post(
            update_post_url,
            {
                'title': '세 번째 포스트를 수정했습니다. ',
                'content': '안녕 세계? 우리는 하나!',
                'category': self.category_music.pk,
                'tags_str': '파이썬 공부; 한글 태그, some tag'
            },
            follow=True
        )
        soup = BeautifulSoup(response.content, 'html.parser')
        main_area = soup.find('div', id='main-area')
        self.assertIn('세 번째 포스트를 수정했습니다.', main_area.text)
        self.assertIn('안녕 세계? 우리는 하나!', main_area.text)
        self.assertIn(self.category_music.name, main_area.text)
        self.assertIn('파이썬 공부', main_area.text)
        self.assertIn('some tag', main_area.text)
        self.assertNotIn('python', main_area.text)

post_update_form.html 수정

<!-- post_update_form.html -->
{% extends 'blog/base_full_width.html' %}

{% block head_title %}Edit Post - Blog{% endblock %}


{% block main_area %}
    <h1>Edit Post</h1>
    <hr/>
    <form method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <table>
            {{ form }}
            <tr>
                <th><label for="id_tags_str">Tags:</label></th>
                <td><input type="text" name="tags_str" id="id_tags_str" value="{{ tags_str_default }}"></td>
            </tr>
        </table>
        <button type="submit" class="btn btn-primary float-end">Submit</button>
    </form>
{% endblock %}

name이 tags_str인 input 태그에 기존의 태그들이 들어있을 수 있도록 value = "{{ tags_str_default }}를 추가한다.

tags_str_default를 정의해주기 위해, PostUpdate에서 값을 넘겨주도록 수정한다.

CBV에서 템플릿에 추가 인자를 넘기려면 get_context_data()를 이용한다.

# views.py
class PostUpdate(LoginRequiredMixin, UpdateView):
    model = Post
    fields = ['title', 'hook_text', 'content', 'head_image', 'file_upload', 'category', 'tags']

    template_name = 'blog/post_update_form.html'

    def get_context_data(self, **kwargs):
        context = super(PostUpdate, self).get_context_data()
        if self.object.tags.exists():
            tags_str_list = list()
            for t in self.object.tags.all():
                tags_str_list.append(t.name)
            context['tags_str_default'] = '; '.join(tags_str_list)

        return context

(...생략...)

PostCreate와 마찬가지로, PostUpdate도 form_valid()를 통해 태그를 추가하도록 해야한다.

# views.py
class PostUpdate(LoginRequiredMixin, UpdateView):
    (...생략...)
    def form_valid(self, form):
        response = super(PostCreate, self).form_valid(form)
        self.object.tags.clear()

        tags_str = self.request.POST.get('tags_str')
        if tags_str:
            tags_str = tags_str.strip()

            tags_str = tags_str.replace(',', ';')
            tags_list = tags_str.split(';')

            for t in tags_list:
                t = t.strip()
                tag, is_tag_created = Tag.objects.get_or_create(name=t)
                if is_tag_created:
                    tag.slug = slugify(t, allow_unicode=True)
                    tag.save()
                self.object.tags.add(tag)

        return response