0401
순서
- like
- like with through
- follow
- hashtag
- gravatar
- git branching..
fontAwesome(https://fontawesome.com/)
이쁜 폰트 써보기
1.like
좋아요 추가하기
article > models.py
like_users = models.ManyToManyField(
settings.AUTH_USER_MODEL, #M:N with User Model
related_name='like_articles', # For User Model
)
마이그레이션, 마이그레이트
폰트어썸 > 마이페이지 > kit > (내코드 복사)
templates > base.html(헤드쪽에 넣어주기)
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://kit.fontawesome.com/80da99576a.js" crossorigin="anonymous"></script>
{% bootstrap_css %}
<title>Document</title>
</head>
폰트어썸에들어가서 마음에드는아이콘 선택후 빨강 동그라미 복사
articles >
detail.html
<h2>DETAIL</h2>
<h3>{{ article.pk }} 번째 글</h3>
<hr>
<p>제목 : {{ article.title }}</p>
<p>내용 : {{ article.content }}</p>
<p>작성시각 : {{ article.created_at|naturalday }}</p>
<p>수정시각 : {{ article.updated_at|naturaltime }}</p>
<hr>
<form action="{% url 'articles:like' article.pk %}" method="POST">
{% csrf_token %}
<button>
<i class="far fa-heart"></i>
</button>
</form>
<hr>
urls.py
#like
path('<int:pk>/like/', views.like, name='like'),
views.py
좋아요와 관련하여 직접 확인해보기
def like(request, pk):
# 1. 좋아요 누른 게시글 가져오기
article = get_object_or_404(Article, pk=pk)
# 2. 게시글 좋아요 누른 유저 목록에
# 내가 없다면 추가하기
print(article.like_users)
print(type(article.like_users))
print(article.like_users.all())
print( help(article.like_users) )
# 3. 게시글 좋아요 누른 유저 목록에
# 재가 있다면 제거하기
return redirect('articles:detail', article.pk)
https://docs.djangoproject.com/en/3.1/ref/models/relations/
related_name 과 관련된 것입니다.
print( help(article.like_users) )
이친구를 한번 보겠습니다.
어디서 뭘상속받았는지 전부 알려주는 친구!
class ManyRelatedManager(django.contrib.auth.models.UserManager)
| ManyRelatedManager(*args, **kwargs)
|
| Method resolution order:
| ManyRelatedManager
| django.contrib.auth.models.UserManager
| django.contrib.auth.base_user.BaseUserManager
| django.db.models.manager.Manager
| django.db.models.manager.BaseManagerFromQuerySet
| django.db.models.manager.BaseManager
| builtins.object
|# 메소드 안만큼 상속을 받았다는 것
| Methods defined here:
|
| __call__(self, *, manager)
|
| __init__(self, instance=None)
|
| add(self, *objs, through_defaults=None)
|
| clear(self)
|
| create(self, *, through_defaults=None, **kwargs)
|
| get_or_create(self, *, through_defaults=None, **kwargs)
#메소드 밑에서부터는 상속받은 클래스들을 보여줍니다.
여튼 뷰로 넘어가서..
def like(request, pk):
# 1. 좋아요 누른 게시글 가져오기
article = get_object_or_404(Article, pk=pk)
# 2. 게시글 좋아요 누른 유저 목록에
# 내가 없다면 추가하기
if article.like_users.filter(pk=request.user.pk).exists():
article.like_users.remove(request.user)
# 3. 게시글 좋아요 누른 유저 목록에
# 내가 있다면 제거하기
else:
article.like_users.add(request.user)
return redirect('articles:detail', article.pk)
DB확인하기
좋아요 몇명이 좋아하는지
detail.html
<p>{{ article.like_users.count}} 명이 좋아합니다.</p>
좋아요 이름. 시간 표시하기
templates. detail html
<div>
{% for like in article.like_set.all %}
<p>유저 : {{ like.user }} | 좋아요 누른 날짜 : {{ like.created_at|naturaltime }} </p>
{% endfor %}
</div>
좋아요 기능 중개테이블
class Like(models.Model):
'''
좋아요 기능을 위한 article과 유저 사이의 중개테이블
'''
article = models.ForeignKey('Article', on_delete=models.CASCADE)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
created_at = models.DataTimeField(auto_now_add=True)# 언제 좋아요 눌렀는지
중개테이블만 만들면안된다
like_users 로가서 through 로가자.
from django.db import models
from django.conf import settings
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=10)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
like_users = models.ManyToManyField(
settings.AUTH_USER_MODEL,
related_name='like_articles',
through='Like',
)
def __str__(self):
return self.title
class Comment(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
content = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.content
class Like(models.Model):
'''
좋아요 기능을 위한 article과 유저 사이의 중개테이블
'''
article = models.ForeignKey('Article', on_delete=models.CASCADE)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
article그리고 마이그레이션 폴더로간다 04,05 를 지운다
그리고 다시 migrations와 migrate를 하면 성공!
그것을 안하면
이런 오류가 발생하니 주의
프로필 추가하기
메인에서 사용자를 눌렀을떄 프로필 페이지로가기
index.html
{% extends 'base.html' %}
{% block content %}
<h1>Articles</h1>
{% if request.user.is_authenticated %}
<a href="{% url 'articles:create' %}">[CREATE]</a>
{% else %}
<a href="{% url 'accounts:login' %}">[새 글을 작성하려면 로그인하세요.]</a>
{% endif %}
<hr>
{% for article in articles %}
<p>
<b>
<a href="{% url 'accounts:profile' article.user.username %}">
작성자 : {{ article.user }}
</a>
</b>
</p>
<p>글 번호 : {{ article.pk }}</p>
<p>글 제목 : {{ article.title }}</p>
<p>글 내용 : {{ article.content }}</p>
<a href="{% url 'articles:detail' article.pk %}">[DETAIL]</a>
<hr>
{% endfor %}
{% endblock %}
accounts > urls.py
from django.urls import path
from . import views
app_name = 'accounts'
urlpatterns = [
path('login/', views.login, name='login'),
path('logout/', views.logout, name='logout'),
path('signup/', views.signup, name='signup'),
path('delete/', views.delete, name='delete'),
path('update/', views.update, name='update'),
path('password/', views.change_password, name='change_password'),
#profile
path('<str:username>/', views.profile, name='profile'),
]
accounts > views.py
from django.shortcuts import render, redirect
from django.contrib.auth import login as auth_login
from django.contrib.auth import logout as auth_logout
# from django.contrib.auth import login as auth_login, logout as auth_logout
from django.views.decorators.http import require_POST, require_http_methods
from django.contrib.auth.decorators import login_required
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.forms import (
AuthenticationForm,
UserCreationForm,
PasswordChangeForm,
)
from .forms import CustomUserChangeForm, CustomUserCreationForm
# Create your views here.
@require_http_methods(['GET', 'POST'])
def login(request):
if request.user.is_authenticated:
return redirect('articles:index')
if request.method == 'POST':
form = AuthenticationForm(request, request.POST)
# form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
auth_login(request, form.get_user())
return redirect(request.GET.get('next') or 'articles:index')
else:
form = AuthenticationForm()
context = {
'form': form,
}
return render(request, 'accounts/login.html', context)
@require_POST
def logout(request):
if request.user.is_authenticated:
auth_logout(request)
return redirect('articles:index')
@require_http_methods(['GET', 'POST'])
def signup(request):
if request.user.is_authenticated:
return redirect('articles:index')
if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
user = form.save()
auth_login(request, user)
return redirect('articles:index')
else:
form = CustomUserCreationForm()
context = {
'form': form,
}
return render(request, 'accounts/signup.html', context)
@require_POST
def delete(request):
if request.user.is_authenticated:
request.user.delete()
auth_logout(request)
return redirect('articles:index')
@login_required
@require_http_methods(['GET', 'POST'])
def update(request):
if request.method == 'POST':
form = CustomUserChangeForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect('articles:index')
else:
form = CustomUserChangeForm(instance=request.user)
context = {
'form': form,
}
return render(request, 'accounts/update.html', context)
@login_required
@require_http_methods(['GET', 'POST'])
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(request.user, request.POST)
# form = PasswordChangeForm(user=request.user, data=request.POST)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
return redirect('articles:index')
else:
form = PasswordChangeForm(request.user)
context = {
'form': form,
}
return render(request, 'accounts/change_password.html', context)
def profile(request, username):
# 1. 현재 요청을 보낸 유저가 보고자하는 유저를 가져오기
from django.contrib.auth import get_user_model
User = get_user_model()
profile_user = User.objects.get(username=username)
context = {
'profile_user':profile_user,
}
return render(request, 'accounts/profile.html', context)
accounts > profile.html
{% extends 'base.html' %}
{% block content %}
<h1>{{ profile_user }}님의 프로필 페이지</h1>
{% comment %} 팔로우 버튼 {% endcomment %}
<form action="" method="POST">
{% csrf_token %}
<button>Follow</button>
</form>
{% comment %} 팔로워 목록 {% endcomment %}
{% comment %} 팔로잉 목록 {% endcomment %}
{% endblock %}
3. 팔로우 만들기
accounts > models.py
from django.db import models
from django.conf import settings
from django.contrib.auth.models import AbstractUser
# Create your models here.
class User(AbstractUser):
followings = models.ManyToManyField('self', related_name='followers',)
forms.py
from django.contrib.auth.forms import UserChangeForm, UserCreationForm
from django.contrib.auth import get_user_model
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = get_user_model()
fields = ('username', 'email', 'first_name', 'last_name',)
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = get_user_model()
fields = UserCreationForm.Meta.fields
철수 > 영희
철수.follwings.all() => [영희, ]
영희.follwings.all() => []
철수.followers.all() =>[영희, ]
영희.followers.all()=>[]
하지만 위에 옵션에서 symmetrical=False 를써줘야지 대칭 수락이안됨 저게없으면
한명이 팔로우를 하게되면 자동으로 팔로워 를 서로 하게된다.
accounts > profile.html
{% extends 'base.html' %}
{% block content %}
<a href="{% url 'articles:index' %}">홈으로가기</a>
<h1>{{ profile_user }}님의 프로필 페이지</h1>
{% comment %} 팔로우 버튼 {% endcomment %}
<form action="{% url 'accounts:follow' profile_user.pk %}" method="POST">
{% csrf_token %}
{% if request.user in profile_user.followers.all %}
<button class="btn btn-danger">UnFollow</button>
{% else %}
<button class="btn btn-primary">Follow</button>
{% endif %}
</form>
{% comment %} 팔로워 목록 {% endcomment %}
<div>
<p>
팔로워 목록 :
{% for follower in profile_user.followers.all %}
{{ follower }}
{% endfor %}
</p>
</div>
{% comment %} 팔로잉 목록 {% endcomment %}
<div>
<p>
팔로잉 목록 :
{% for following in profile_user.followers.all %}
{{ following }}
{% endfor %}
</p>
</div>
{% endblock %}
urls.py
def follow(request, pk):
# User = get_user_model()
# #팔로우
# user = get_object_or_404(User, pk=pk)
# if user != request.user:
# #팔로워 ==> request.user
# #만약에 팔로워라면?
# if user.follow.filter(pk=request.user.pk).exists():
# user.follow.remove(request.user) #삭제하기
# else:
# user.follow.add(request.user)
# return redirect('accounts:profile', user.username)
User = get_user_model() # User 모델 == 클래스
you = get_object_or_404(User, pk=pk)
me = request.user
if you.followers.filter(pk=me.pk).exists():
you.followers.remove(me)
else:
you.followers.add(me)
return redirect('accounts:profile', you.username)
4. hashtag
articles. models.py
from django.db import models
from django.conf import settings
# Create your models here.
class Hashtag(models.Model):
content = models.TextField(unique=True)
class Article(models.Model):
hashtags = models.ManyToManyField( 'Hashtag', related_name='articles', blank=True, ) #blank=true 는 유효성 검사에서 제외하겠다.
title = models.CharField(max_length=10)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
like_users = models.ManyToManyField(
settings.AUTH_USER_MODEL,
related_name='like_articles',
through='Like',
)
def __str__(self):
return self.title
class Comment(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
content = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.content
class Like(models.Model):
'''
좋아요 기능을 위한 article과 유저 사이의 중개테이블
'''
article = models.ForeignKey('Article', on_delete=models.CASCADE)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
.# 이하 hastag 를 해주려면 파싱을 해줘야한다.
articles. views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect, get_object_or_404
from django.views.decorators.http import require_safe, require_http_methods, require_POST
from django.http import HttpResponse, HttpResponseForbidden
from .models import Article, Comment, Hashtag
from .forms import ArticleForm, CommentForm
# Create your views here.
@require_safe
def index(request):
articles = Article.objects.order_by('-pk')
context = {
'articles': articles,
}
return render(request, 'articles/index.html', context)
@login_required
@require_http_methods(['GET', 'POST'])
def create(request):
if request.method == 'POST':
form = ArticleForm(request.POST)
if form.is_valid():
article = form.save(commit=False)
article.user = request.user
article.save()
#hashtag
for word in article.content.split():
# word : ex) 오늘 # 장고 # 많이 #힘들다
if word.startswith('#'):
# 해쉬태그 테이블에 우선 새로운 데이터를 생성하고
hashtag = Hashtag.objects.create(content=word)
# 방금 생성된 해쉬태그와 현재 게시글을 관계 지어준다.
# (article 과 hashtag의 중개 테이블에 관계르 생성하는 부분)
article.hashtags.add(hashtag)
return redirect('articles:detail', article.pk)
else:
form = ArticleForm()
context = {
'form': form,
}
return render(request, 'articles/create.html', context)
@require_safe
def detail(request, pk):
article = get_object_or_404(Article, pk=pk)
comment_form = CommentForm()
comments = article.comment_set.all()
context = {
'article': article,
'comment_form': comment_form,
'comments': comments,
}
return render(request, 'articles/detail.html', context)
@require_POST
def delete(request, pk):
article = get_object_or_404(Article, pk=pk)
if request.user.is_authenticated:
if request.user == article.user:
article.delete()
return redirect('articles:index')
return redirect('articles:detail', article.pk)
@login_required
@require_http_methods(['GET', 'POST'])
def update(request, pk):
article = get_object_or_404(Article, pk=pk)
if request.user == article.user:
if request.method == 'POST':
form = ArticleForm(request.POST, instance=article)
if form.is_valid():
form.save()
return redirect('articles:detail', article.pk)
else:
form = ArticleForm(instance=article)
else:
return redirect('articles:index')
# return HttpResponseForbidden()
context = {
'form': form,
'article': article,
}
return render(request, 'articles/update.html', context)
@require_POST
def comments_create(request, pk):
if request.user.is_authenticated:
article = get_object_or_404(Article, pk=pk)
comment_form = CommentForm(request.POST)
if comment_form.is_valid():
comment = comment_form.save(commit=False)
comment.article = article
comment.user = request.user
comment.save()
return redirect('articles:detail', article.pk)
context = {
'comment_form': comment_form,
'article': article,
}
return render(request, 'articles/detail.html', context)
return redirect('accounts:login')
# return HttpResponse(status=401)
@require_POST
def comments_delete(request, article_pk, comment_pk):
if request.user.is_authenticated:
comment = get_object_or_404(Comment, pk=comment_pk)
if request.user == comment.user:
comment.delete()
# return HttpResponseForbidden()
return redirect('articles:detail', article_pk)
# return HttpResponse(status=401)
def like(request, pk):
# 1. 좋아요 누른 게시글 가져오기
article = get_object_or_404(Article, pk=pk)
# 2. 게시글 좋아요 누른 유저 목록에
# 내가 없다면 추가하기
if article.like_users.filter(pk=request.user.pk).exists():
article.like_users.remove(request.user)
# 3. 게시글 좋아요 누른 유저 목록에
# 내가 있다면 제거하기
else:
article.like_users.add(request.user)
return redirect('articles:detail', article.pk)
create 세이브 함수 밑에서 넣는다.
중복으로 해시테그가 사용이안된다.
우리는 get_or_create()를 사용해볼것이다.
https://docs.djangoproject.com/en/3.1/ref/models/querysets/#get-or-create
https://docs.djangoproject.com/en/3.1/howto/custom-template-tags/
를 보자
articles 에 폴더를 하나만든다.
hashtag_link.pk
from django import template
register = template.Library()
@register.filter
def hashtag_check(article):
'''
article의 content를 파싱해서 #으로 시작하는 단어들을
a태그로 감싸줍니다.
ex) {{ article|hashtag_check }}
'''
content = article.content
hashtags = article.hashtags.all() # #디장고 #오늘
for hashtag in hashtags:
# #디장고 => <a href="">#디장고 </a>
content = content.replace(
hashtag.content,
f'<a href="#">{hashtag.content}</a>'
)
return content
detail.html
{% load hashtag_link %}
<p>내용 : {{ article|hashtag_check }}</p>
{% extends 'base.html' %}
{% load humanize %}
{% load hashtag_link %}
{% block content %}
<h2>DETAIL</h2>
<h3>{{ article.pk }} 번째 글</h3>
<hr>
<p>제목 : {{ article.title }}</p>
<p>내용 : {{ article|hashtag_check }}</p>
<p>작성시각 : {{ article.created_at|naturalday }}</p>
<p>수정시각 : {{ article.updated_at|naturaltime }}</p>
<hr>
<form action="{% url 'articles:like' article.pk %}" method="POST">
{% csrf_token %}
<button class="btn btn-white">
{% if request.user not in article.like_users.all %}
<i class="far fa-heart"></i>
{% else %}
<i class="fas fa-heart" style="color: red;"></i>
{% endif %}
</button>
</form>
<p>{{ article.like_users.count}} 명이 좋아합니다.</p>
<div>
{% for like in article.like_set.all %}
<p>유저 : {{ like.user }} | 좋아요 누른 날짜 : {{ like.created_at|naturaltime }} </p>
{% endfor %}
</div>
<hr>
{% if request.user == article.user %}
<a href="{% url 'articles:update' article.pk %}" class="btn btn-primary">[UPDATE]</a>
<form action="{% url 'articles:delete' article.pk %}" method="POST">
{% csrf_token %}
<button class="btn btn-danger">DELETE</button>
</form>
{% endif %}
<a href="{% url 'articles:index' %}">[back]</a>
<hr>
<h4>댓글 목록</h4>
<p>{{ comments|length }}개의 댓글이 있습니다.</p>
<ul>
{% for comment in comments %}
<li>
{{ comment.user }} - {{ comment.content }}
{% if request.user == comment.user %}
<form action="{% url 'articles:comments_delete' article.pk comment.pk %}" method="POST" class="d-inline">
{% csrf_token %}
<input type="submit" value="DELETE">
</form>
{% endif %}
</li>
{% empty %}
<p>아직 댓글이 없네요...</p>
{% endfor %}
</ul>
<hr>
{% if request.user.is_authenticated %}
<form action="{% url 'articles:comments_create' article.pk %}" method="POST">
{% csrf_token %}
{{ comment_form }}
<input type="submit">
</form>
{% else %}
<a href="{% url 'accounts:login' %}">[댓글을 작성하려면 로그인 하세요.]</a>
{% endif %}
{% endblock %}
이렇게하면 게시판에
a태그가 붙습니다
다만 장고의 보안때문에 html의 약간의 추가가 필요ㅕ합니다.(safe)
<p>내용 : {{ article|hashtag_check|safe }}</p>
그러고 나면
잘됩니다만 해쉬테그가 잘안되는 것은 알고리즘 수정이필요합니다
ex) create 부분의 해쉬태그 알고리즘부분 수정필요
해쉬태그를 클리갛면 게시물 전부불러오기
articles. urls.py
from django.urls import path
from . import views
app_name = 'articles'
urlpatterns = [
path('', views.index, name='index'),
path('create/', views.create, name='create'),
path('<int:pk>/', views.detail, name='detail'),
path('<int:pk>/delete/', views.delete, name='delete'),
path('<int:pk>/update/', views.update, name='update'),
path('<int:pk>/comments/', views.comments_create, name='comments_create'),
path('<int:article_pk>/comments/<int:comment_pk>/delete/', views.comments_delete, name='comments_delete'),
#like
path('<int:pk>/like/', views.like, name='like'),
#hashtag
path('<int:hash_pk>/hashtag/', views.hashtag, name="hashtag"),
]
views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect, get_object_or_404
from django.views.decorators.http import require_safe, require_http_methods, require_POST
from django.http import HttpResponse, HttpResponseForbidden
from .models import Article, Comment, Hashtag
from .forms import ArticleForm, CommentForm
# Create your views here.
@require_safe
def index(request):
articles = Article.objects.order_by('-pk')
context = {
'articles': articles,
}
return render(request, 'articles/index.html', context)
@login_required
@require_http_methods(['GET', 'POST'])
def create(request):
if request.method == 'POST':
form = ArticleForm(request.POST)
if form.is_valid():
article = form.save(commit=False)
article.user = request.user
article.save()
#hashtag
for word in article.content.split():
# word : ex) 오늘 # 장고 # 많이 #힘들다
if word.startswith('#'):
# 해쉬태그 테이블에 우선 새로운 데이터를 생성하고
hashtag, created = Hashtag.objects.get_or_create(content=word)
# 방금 생성된 해쉬태그와 현재 게시글을 관계 지어준다.
# (article 과 hashtag의 중개 테이블에 관계르 생성하는 부분)
article.hashtags.add(hashtag)
return redirect('articles:detail', article.pk)
else:
form = ArticleForm()
context = {
'form': form,
}
return render(request, 'articles/create.html', context)
@require_safe
def detail(request, pk):
article = get_object_or_404(Article, pk=pk)
comment_form = CommentForm()
comments = article.comment_set.all()
context = {
'article': article,
'comment_form': comment_form,
'comments': comments,
}
return render(request, 'articles/detail.html', context)
@require_POST
def delete(request, pk):
article = get_object_or_404(Article, pk=pk)
if request.user.is_authenticated:
if request.user == article.user:
article.delete()
return redirect('articles:index')
return redirect('articles:detail', article.pk)
@login_required
@require_http_methods(['GET', 'POST'])
def update(request, pk):
article = get_object_or_404(Article, pk=pk)
if request.user == article.user:
if request.method == 'POST':
form = ArticleForm(request.POST, instance=article)
if form.is_valid():
article = form.save()
#hashtag
# update 에서는 hashtag 관꼐를 초기화 해줘야함
# 기존의 해쉬태그도 수정
article.hashtags.clear()
for word in article.content.split():
# word : ex) 오늘 # 장고 # 많이 #힘들다
if word.startswith('#'):
# 해쉬태그 테이블에 우선 새로운 데이터를 생성하고
hashtag, created = Hashtag.objects.get_or_create(content=word)
# 방금 생성된 해쉬태그와 현재 게시글을 관계 지어준다.
# (article 과 hashtag의 중개 테이블에 관계르 생성하는 부분)
article.hashtags.add(hashtag)
return redirect('articles:detail', article.pk)
else:
form = ArticleForm(instance=article)
else:
return redirect('articles:index')
# return HttpResponseForbidden()
context = {
'form': form,
'article': article,
}
return render(request, 'articles/update.html', context)
@require_POST
def comments_create(request, pk):
if request.user.is_authenticated:
article = get_object_or_404(Article, pk=pk)
comment_form = CommentForm(request.POST)
if comment_form.is_valid():
comment = comment_form.save(commit=False)
comment.article = article
comment.user = request.user
comment.save()
return redirect('articles:detail', article.pk)
context = {
'comment_form': comment_form,
'article': article,
}
return render(request, 'articles/detail.html', context)
return redirect('accounts:login')
# return HttpResponse(status=401)
@require_POST
def comments_delete(request, article_pk, comment_pk):
if request.user.is_authenticated:
comment = get_object_or_404(Comment, pk=comment_pk)
if request.user == comment.user:
comment.delete()
# return HttpResponseForbidden()
return redirect('articles:detail', article_pk)
# return HttpResponse(status=401)
def like(request, pk):
# 1. 좋아요 누른 게시글 가져오기
article = get_object_or_404(Article, pk=pk)
# 2. 게시글 좋아요 누른 유저 목록에
# 내가 없다면 추가하기
if article.like_users.filter(pk=request.user.pk).exists():
article.like_users.remove(request.user)
# 3. 게시글 좋아요 누른 유저 목록에
# 내가 있다면 제거하기
else:
article.like_users.add(request.user)
return redirect('articles:detail', article.pk)
def hashtag(request, hash_pk):
tag = get_object_or_404(Hashtag, pk=hash_pk)
context = {
'tag':tag,
}
return render(request, 'articles/hashtag.html', context)
hashtag.html
related_name 을 articles 로 설정했다. for 문에
{% extends 'base.html' %}
{% block content %}
<h1>{{ tag.content }}</h1>
<hr>
<div>
{% for article in tag.articles.all %}
제목 : {{ article.title }}
{% endfor %}
</div>
{% endblock %}
hashtag_link.py
from django import template
register = template.Library()
@register.filter
def hashtag_check(article):
'''
article의 content를 파싱해서 #으로 시작하는 단어들을
a태그로 감싸줍니다.
ex) {{ article|hashtag_check }}
'''
content = article.content
hashtags = article.hashtags.all() # #디장고 #오늘
for hashtag in hashtags:
# #디장고 => <a href="">#디장고 </a>
content = content.replace(
hashtag.content,
f'<a href="/articles/{hashtag.pk}/hashtag/">{hashtag.content}</a>'
)
return content
5. branching
가장 최신 commit 을 불러온다? 준다?
협업할떄 쓰는 것입니둥두둥
협업하기 폴더 안에서
django-admin startproject config .
gitstatus
git add.
git commit -m "install"
팀원
git checkout -b 'hwangsoengahn'
#브랜치를 만들어서 그 공간으로 이동하는것
git add.
git log
python manage.py startapp soengahn
# 성안 파이썬 폴더만들기
git commit -m "add soengahn"
git push origin 이름
merge request
푸시만했다고 병합된건 아니다
왼쪽에 merge request를보거나 우측 상단에 create reques
병합 요청을한다(프로젝트팀장)
이건 충돌되있다는 뜻
이중에 괜찮은 아이디어가있다면 merge 를 팀장이 클릭해서 머지해준다.
그리고 항상 gitignore 신경써주자.
프로젝트 끝났으면 지우자
git checkout master
git branch -D hwangseongahn
git checkout -b 'HSA/'
만약 모르고 마스터로 푸시해버리면?
'SSAFY > Django' 카테고리의 다른 글
[Django] swagger (0) | 2021.04.27 |
---|---|
[Django] REST - API ( 맛보기 ) (0) | 2021.04.26 |
[Django] 로그인한 사용자 판별하기 (0) | 2021.03.27 |
[Django] 댓글 삭제 (0) | 2021.03.26 |
[Django] SQL 과 장고 ORM 사용 방법 (0) | 2021.03.26 |