django 5-4 해시태그

Grace Goh·2022년 10월 13일
0

Django

목록 보기
27/32

1. module 다운로드

서버를 종료하고 명령어를 입력한다.

pip install django-taggit
pip install django-taggit-templatetags2

2. settings.py에 알려주기

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'tweet',
    'user',
    'restaurant',
    'taggit.apps.TaggitAppConfig', # 이하를 추가
    'taggit_templatetags2',
]

TAGGIT_CASE_INSENSITIVE = True
TAGGIT_LIMIT = 50

3. 모델에 적용하기

우리 TweetModel 안에 django의 tag 서비스를 적용하기.
먼저 태그를 넣을 수 있는 모듈을 설치한다.

# tweet/models.py

from taggit.managers import TaggableManager

TaggableManager : 글에 태그를 넣을 수 있게 해준다.

4. DB에 적용하기

class TweetModel(models.Model):
    class Meta:
        db_table = "tweet"

    author = models.ForeignKey(UserModel, on_delete=models.CASCADE)
    content = models.CharField(max_length=256)
    tags = TaggableManager(blank=True) # 추가
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

(blank=True) 비어 있어도 작동하겠다는 의미.

5. migrations

사전 작업이 끝났기 때문에 DB와 migration 해준다.
migrate : 방금 수정한 내용을 DB에 적용한다.

6. view 만들기

글을 입력할 때 태그를 입력하기 때문에 글을 쓰는 tweet의 POST로 간다.

# tweet/views.py
def tweet(request):
    if request.method == 'GET':
        user = request.user.is_authenticated
        if user:
            all_tweet = TweetModel.objects.all().order_by('-created_at')
            return render(request, 'tweet/home.html', {'tweet':all_tweet})
        else:
            return redirect('/sign-in')

    elif request.method == 'POST':
        user = request.user
        content = request.POST.get('my-content', '')
        tags = request.POST.get('tag', '').split(',') 
        # user, content만 있는데 tags를 추가한다.

tags = request.POST.get('tag', '').split(',')
태그를 외부(웹 화면)에서 django 서버로 불러오는 태그다.

  • 이것을 작성했기 때문에 나중에 화면을 바꿔줘야 한다.
    아이디와 네임을 태그로 갖고 있는 input 태그를 만들어야 한다.

해당 태그 목록을 아래와 같이 for문으로 분리한다.

위 태그는 my_tweet.save() 쪽에서 같이 저장해준다.

        if content == '':
            all_tweet = TweetModel.objects.all().order_by('-created_at')
            return render(request, 'tweet/home.html', {'error':'글은 공백일 수 없습니다.', 'tweet':all_tweet})
        else:
            my_tweet = TweetModel.objects.create(author=user, content=content)
            for tag in tags: # [리스트] 형태. 태그 하나하나를 다시 수정한다.
                tag = tag.strip() # 공백을 제거하고 넣어준다.
                if tag != '': # 태그가 비어 있지 않다면 (내용이 있다면)
                    my_tweet.tags.add(tag) # 트윗모델의 태그를 불러서 추가해주는 작업
            my_tweet.save()
            return redirect('/tweet')

tweet이 완료되었다.

6-1. django taggit

아래는 django taggit으로 검색하면 나오는 공식 document를 일부 수정한 것이다. 그대로 붙여 넣으면 된다.

# tweet/views.py
from django.views.generic import ListView, TemplateView # 추가


# (...)


# tag_cloud_view.html을 보여주겠다.
class TagCloudTV(TemplateView):
    template_name = 'taggit/tag_cloud_view.html'

# 태그가 있으면 태그를 보여주겠다.
class TaggedObjectLV(ListView):
    template_name = 'taggit/tag_with_post.html'
    model = TweetModel

    def get_queryset(self):
        return TweetModel.objects.filter(tags__name=self.kwargs.get('tag'))

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['tagname'] = self.kwargs['tag']
        return context

7. url 설정하기

model과 view가 설정되었으니 url을 설정해준다.

# tweet/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('tweet/', views.tweet, name='tweet'),
    path('tweet/delete/<int:id>', views.delete_tweet, name='delete-tweet'),
    path('tweet/<int:id>', views.detail_tweet, name='detail-tweet'),
    path('tweet/comment/<int:id>', views.write_comment, name='write-comment'),
    path('tweet/comment/delete/<int:id>', views.delete_comment, name='delete-comment'),
    # 이하를 추가한다. 태그로 접근하면 다음 함수가 실행된다.
    path('tag/', views.TagCloudTV.as_view(), name='tag_cloud'),
    # 태그 내 문자열로 들어가면
    path('tag/<str:tag>/', views.TaggedObjectLV.as_view(), name='tagged_object_list'),
]

url과 view 작업을 했고 html이 남았다.


8. html 추가하기

# templates/tweet/home.html

<textarea class="form-control" style="resize: none" name='my-content'
          id="my-content"></textarea>
# 이하를 추가한다!
<div class="mt-3 row"> 
    <label for="tag"
           class="col-sm-2 col-form-label">이 글의 태그</label>
    <div class="col-sm-10">
        <input type="text" class="form-control" name="tag" id="tag"
               placeholder="콤마(,)로 구분 해 주세요">
    </div>
</div>

내 글에 tag가 있으면 보여주겠다.

<h5 class="mt-0">{{ tw.content }}</h5>
# 이하를 추가한다.
{% if tw.tags.all %}
    {% for tag in tw.tags.all %}
        <a style="text-decoration: none"
           href="{% url 'tagged_object_list' tag.name %}">
        <span class="badge rounded-pill bg-success">
            {{ tag.name }}
        </span>
        </a>
    {% endfor %}
    -<a style="text-decoration: none"
        href="{% url 'tag_cloud' %}">TagCloud</a>
{% endif %}

tweet_detail.html

<h5 class="mt-0">{{ tweet.content }}</h5>
# 이하를 추가한다.
{% if tweet.tags.all %}
    {% for tag in tweet.tags.all %}
        <a style="text-decoration: none" href="{% url 'tagged_object_list' tag.name %}">
            <span class="badge rounded-pill bg-success">
                {{ tag.name }}
            </span>
        </a>
    {% endfor %}
    -<a style="text-decoration: none"
        href="{% url 'tag_cloud' %}">TagCloud</a>
{% endif %}

9. html 생성하기

templates/taggit/tag_with_post.html

{% extends "base.html" %}

{% block title %}태그 글 리스트{% endblock %}

{% block content %}

    <div class="container">
        <h3 class="mt-2">Posts for tag - {{ tagname }}</h3>
        <hr>
        <div class="card">
            <div class="card-body">
                {% for tweet in object_list %}
                    <h4>
                        <a href="/tweet/{{ tweet.id }}">{{ tweet.content }}</a>
                    </h4>
                    {{ tweet.updated_at|timesince}}
                    <p> {{ tweet.author }}</p>
                {% endfor %}
            </div>
        </div>
    </div>
{% endblock %}

templates/taggit/tag_cloud_view.html

{% extends "base.html" %}

{% block title %}태그 클라우드{% endblock %}


{% block content %}

    <div class="container timeline-container">
        <div class="tag-cloud">
            {% load taggit_templatetags2_tags %}
            {% get_tagcloud as tags %} <!--모든 태그 추출해서 tags변수에 할당-->
            {% for tag in tags %}
                    <a style="text-decoration: none" href="{% url 'tagged_object_list' tag.name %}">
                        <span class="badge rounded-pill bg-primary">
                            {{ tag.name }}({{ tag.num_times }})
                        </span>
                    </a>
            {% endfor %}
        </div>
    </div>

{% endblock %}
profile
Español, Inglés, Coreano y Python

0개의 댓글