728x90
반응형
종합 DJANGO code
목차
CRUD
articles
- html
accounts
- html
1. CRUD
settings.py
"""
Django settings for crud project.
Generated by 'django-admin startproject' using Django 3.1.7.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.1/ref/settings/
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '%(+btt9tv$a*@)^r07dbjjgsn&zyuglqka9dw^h@9go7y&r$i&'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'articles',
'accounts',
'bootstrap5',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'crud.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'crud' / 'templates',],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'crud.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/
LANGUAGE_CODE = 'ko-kr'
TIME_ZONE = 'Asia/Seoul'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/
STATIC_URL = '/static/'
AUTH_USER_MODEL = 'accounts.User'
urls.py
"""crud URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('articles/', include('articles.urls')),
path('accounts/', include('accounts.urls')),
]
2. articles
models.py
from django.db import models
from django.conf import settings
# Create your models here.
class Article(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
like_users = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='like_articles')
title = models.CharField(max_length=10)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
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
forms.py
from django import forms
from .models import Article, Comment
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ('title', 'content',)
# exclude = ('title',)
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
# fields = '__all__'
exclude = ('article', 'user',)
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'),
path('<int:article_pk>/likes/', views.likes, name='likes'),
]
views.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'),
path('<int:article_pk>/likes/', views.likes, name='likes'),
]
admins.py
from django.contrib import admin
from .models import Article, Comment
# Register your models here.
admin.site.register(Article)
admin.site.register(Comment)
2-1. templates\articles
create.html
{% extends 'base.html' %}
{% load bootstrap5 %}
{% block content %}
<h1>CREATE</h1>
<form action="" method="POST">
{% csrf_token %}
{% bootstrap_form form %}
<input type="submit">
</form>
<hr>
<a href="{% url 'articles:index' %}">[back]</a>
{% endblock %}
detail.html
{% extends 'base.html' %}
{% load humanize %}
{% block content %}
<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>
{% 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 %} 커멘트폼은 과연 views.py의 detail의 comment부분과 같을까? {% endcomment %}
{{ comment_form }}
<input type="submit">
</form>
{% else %}
<a href="{% url 'accounts:login' %}">[댓글을 작성하려면 로그인 하세요.]</a>
{% endif %}
{% endblock %}
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>
<div>
<form action="{% url 'articles:likes' article.pk %}" method="POST">
{% csrf_token %}
{% if request.user in article.like_users.all %}
<button>좋아요 취소</button>
{% else %}
<button>좋아요</button>
{% endif %}
</form>
</div>
<p>{{ article.like_users.all|length }}명이 이 글을 좋아합니다.</p>
<a href="{% url 'articles:detail' article.pk %}">[DETAIL]</a>
<hr>
{% endfor %}
{% endblock %}
update.html
{% extends 'base.html' %}
{% load bootstrap5 %}
{% block content %}
<h1>UPDATE</h1>
<form action="" method="POST">
{% csrf_token %}
{% bootstrap_form form %}
<input type="submit">
</form>
<hr>
<a href="{% url 'articles:index' %}">[back]</a>
{% endblock %}
3. accounts
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class User(AbstractUser):
followings = models.ManyToManyField('self', symmetrical=False, 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 = ('email', 'first_name', 'last_name',)
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = get_user_model()
fields = UserCreationForm.Meta.fields
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'),
path('<username>/', views.profile, name='profile'),
path('<int:user_pk>/follow/', views.follow, name='follow'),
]
views.py
from django.shortcuts import render, redirect, get_object_or_404
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, get_user_model
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):
person = get_object_or_404(get_user_model(), username=username)
context = {
'person': person,
}
return render(request, 'accounts/profile.html', context)
@require_POST
def follow(request, user_pk):
if request.user.is_authenticated:
# 팔로우 받는 사람
you = get_object_or_404(get_user_model(), pk=user_pk)
me = request.user
# 나 자신은 팔로우 할 수 없다.
if you != me:
if you.followers.filter(pk=me.pk).exists():
# if request.user in person.followers.all():
# 팔로우 끊음
you.followers.remove(me)
else:
# 팔로우 신청
you.followers.add(me)
return redirect('accounts:profile', you.username)
return redirect('accounts:login')
admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User
# Register your models here.
admin.site.register(User, UserAdmin)
3. templates\accounts
change_password.html
{% extends 'base.html' %}
{% block content %}
<h1>비밀번호변경</h1>
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
{% endblock %}
login.html
{% extends 'base.html' %}
{% block content %}
<h1>로그인</h1>
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
{% endblock %}
profile.html
{% extends 'base.html' %}
{% block content %}
<h1>{{ person.username }}님의 프로필</h1>
{% with followings=person.followings.all followers=person.followers.all %}
<div>
<div>
팔로잉 : {{ followings|length }} / 팔로워 : {{ followers|length }}
</div>
{% if request.user != person %}
<div>
<form action="{% url 'accounts:follow' person.pk %}" method="POST">
{% csrf_token %}
{% if request.user in followers %}
<button>언팔로우</button>
{% else %}
<button>팔로우</button>
{% endif %}
</form>
</div>
{% endif %}
</div>
{% endwith %}
<hr>
<h2>{{ person.username }}'s 게시글</h2>
{% for article in person.article_set.all %}
<div>{{ article.title }}</div>
{% endfor %}
<hr>
<h2>{{ person.username }}'s 댓글</h2>
{% for comment in person.comment_set.all %}
<div>{{ comment.content }}</div>
{% endfor %}
<hr>
<h2>{{ person.username }}'s likes</h2>
{% for article in person.like_articles.all %}
<div>{{ article.title }}</div>
{% endfor %}
<hr>
<a href="{% url 'articles:index' %}">[back]</a>
{% endblock %}
signup.html
{% extends 'base.html' %}
{% block content %}
<h1>회원가입</h1>
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
{% endblock %}
update.html
{% extends 'base.html' %}
{% block content %}
<h1>회원정보수정</h1>
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
{% endblock %}
728x90
반응형
'SSAFY > Django' 카테고리의 다른 글
[JS] Vue 기본 (0) | 2021.05.08 |
---|---|
[Django] Dog api(댕댕이 랜덤 추출기) html 만들기! (0) | 2021.05.03 |
Dom 실무? (0) | 2021.04.29 |
[Django] Dom (0) | 2021.04.28 |
[Django] swagger (0) | 2021.04.27 |