티스토리 뷰
(macOS)[python][django][RaspberryPi] ERP platform - 5 : home, notice
jinozpersona 2021. 5. 13. 13:15Template 확장
입력 form 만들기
새글 쓰기/수정/삭제
Server Test : git transmission : 생략
INTRO
* local / server terminal 구분 : [macOS] / [Raspi]
** venv 표기 : (pyERP)
Raspi : server
- Python : 3.7.3
- django : 3.2
macOS : local-dev
- Python : 3.9.4
- django : 3.2
-------------------- platform review --------------------
login 후
home_welcome.html
구성 : head / navbar_main / body_top / navbar_sub / body_bottom / footer
프레임(상단) : user_info
프레임(하단) : notice_list
공지사항 제목 클릭 : notice 이동
새글쓰기 클릭 : notice new
수정하기 클릭 : notice new
삭제하기 클릭 : notice delete, 미리보기 없음
-------------------- platform review --------------------
1번 notice part를 이해하면 2번, 3번은 유사한 포멧으로 완성 가능
1. home: notice
다음과 같이 models/forms/urls/views/templates로 구성
--> models, forms, (admin), urls, views, templates(route : 공통부분, navbar부분 ), templates(home), css
2. sales
3. production
@ macOS
Home : notice
- models : 조회수 카운팅 추가 및 구현
{SublimeText} home/models.py
from django.db import models
from django.conf import settings
class Notice(models.Model):
notice_id = models.AutoField(primary_key=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=False)
title = models.CharField('제목', max_length=128, null=False)
article = models.TextField('내용', null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
hit = models.PositiveIntegerField(default=0)
def __str__(self):
return self.title
@property
def hit_cnt(self):
self.hit = self.hit + 1
self.save()
- forms
{SublimeText} home/forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from home.models import Notice
class NoticeForm(forms.ModelForm):
class Meta:
model = Notice
fields = ['author', 'title', 'article']
widgets = {
'title' : forms.TextInput(attrs={'style':'width: 12em'}),
'article' : forms.Textarea(attrs={'style':'width: 40em', 'rows':4}),
}
- admin
{SublimeText} home/admin.py
from django.contrib import admin
from home.models import Notice
class NoticeAdmin(admin.ModelAdmin):
search_fields = ['title']
admin.site.register(Notice, NoticeAdmin)
- urls
{SublimeText} home/urls.py
from django.contrib import admin
from django.urls import path
from home import views
urlpatterns = [
path('', views.home_welcome, name='home_welcome'),
path('notice/<int:pk>/', views.notice, name='notice'),
path('notice/new/', views.notice_new, name='notice_new'),
path('notice/<int:pk>/edit/', views.notice_edit, name='notice_edit'),
path('notice/<int:pk>/delete/', views.notice_delete, name='notice_delete'),
]
- views
{SublimeText} home/views.py
from django.shortcuts import render, redirect
from django.contrib import auth
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from django.contrib.auth.decorators import login_required
from home.models import Notice
from home.forms import NoticeForm
def signup(request):
if request.method == 'POST':
if request.POST['password1'] == request.POST['password2']:
user = User.objects.create_user(username=request.POST['username'], password=request.POST['password1'], email=request.POST['email'], is_active=False)
auth.login(request, user)
return render(request, 'signup_waiting.html', {'user':user})
return redirect('/')
return render(request, 'signup.html')
@login_required
def home_welcome(request):
notices = Notice.objects.all().order_by('-notice_id')
return render(request, 'home_welcome.html', {'notices': notices})
@login_required
def notice(request, pk):
notices = Notice.objects.all().order_by('-notice_id')
notice_view = Notice.objects.get(pk=pk)
context = {'notices': notices, 'notice_view': notice_view}
return render(request, 'notice.html', context)
@login_required
def notice_new(request):
notices = Notice.objects.all().order_by('-notice_id')
if request.method == 'POST':
form = NoticeForm(request.POST)
if form.is_valid():
notice_new = Notice()
notice_new.author = form.cleaned_data['author']
notice_new.title = form.cleaned_data['title']
notice_new.article = form.cleaned_data['article']
notice_new.save()
return redirect('/home/')
else:
form = NoticeForm()
pass
return render(request, 'notice_new.html', {'notices':notices,'form':form})
@login_required
def notice_delete(request, pk):
notice_del = Notice.objects.get(pk=pk)
if notice_del.author == User.objects.get(username = request.user.get_username()):
notice_del.delete()
return redirect('/home/')
else:
return render(request, 'warning.html')
@login_required
def notice_edit(request, pk):
notices = Notice.objects.all().order_by('-notice_id')
notice_edit = Notice.objects.get(pk=pk)
if request.method == 'POST':
form = NoticeForm(request.POST)
if form.is_valid():
notice_edit.author = form.cleaned_data['author']
notice_edit.title = form.cleaned_data['title']
notice_edit.article = form.cleaned_data['article']
notice_edit.save()
return redirect('/home/')
else:
form = NoticeForm()
pass
return render(request, 'notice_edit.html', {'form':form, 'notices':notices})
- templates : route(공통)
{SublimeText} templates/base.html
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}{{ section.title }}{% endblock %}</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="{% static 'css/style_home.css' %}">
</head>
<body>
<div id="container">
<div id="header">
<div class="logo">
<a href="{% url 'home_welcome' %}"><img src="{% static 'img/logo_w_persona.png' %}" width="140" height="38"></a>
</div>
<div class="h-item">
{% if user.is_authenticated %}
<a href="{% url 'logout' %}"><input type="submit" value="{{ user.username }} (Logout)"></a>
{% else %}
<a href="{% url 'login' %}"><input type="submit" value="Login"></a>
{% endif %}
</div>
<div class="search-item">
<input type="search" name="q" placeholder="Search query">
<input type="submit" value="Go!">
</div>
</div>
<!--navbar_top -->
{% block navbar_top %}
{% endblock %}
<!-- Main block -->
<div id="m-content">
{% block content1 %}
{% endblock %}
</div>
<!--navbar_sub -->
{% block navbar_sub %}
{% endblock %}
<!-- Sub block -->
<div id="s-content">
{% block content2 %}
{% endblock %}
</div>
<div id="footer">
<p>Copyright © PERSONA All rights reversed.</p>
</div>
</div>
</body>
</html>
{SublimeText} templates/welcome.html
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Welcome_PERSONA_ERP</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="{% static 'css/style_home.css' %}">
</head>
<body>
<div id="container">
<div id="header">
<!-- <h1>Responsive Layout</h1> -->
<div class="logo">
<a href="{% url 'welcome' %}"><img src="{% static 'img/logo_w_persona.png' %}" width="140" height="38"></a>
</div>
<div class="h-item">
<a href="{% url 'login' %}"><input type="submit" value="Login"></a>
<a href="{% url 'signup' %}"><button type="submit">Sign-Up</button></a>
</div>
</div>
<div id="m-content">
<h2>Thanks to visit PERSONA ERP</h2>
<h3>기존회원로그인</h3>
<p>로그인 후 모든 서비스를 사용할 수 있음.</p>
<h3>회원가입안내</h3>
<p>회원가입 승인 후 모든 서비스를 사용할 수 있음.</p>
</div>
{% block logform %}
{% endblock %}
<div id="footer">
<p>Copyright © PERSONA All rights reversed.</p>
</div>
</div>
</body>
</html>
{SublimeText} templates/login.html
{% extends 'welcome.html' %}
{% block logform %}
{% include "navbar_login.html" %}
<div id="s-content">
<div>
<form method="POST" class="post-form" action="{% url 'login' %}">
{% csrf_token %}
{% include "form_errors.html" %}
<div>
<label for="username">User-ID</label><br>
<input type="text" name="username" id="username"
value="{{ form.username.value|default_if_none:'' }}">
</div>
<div>
<label for="password">Password</label><br>
<input type="password" name="password" id="password"
value="{{ form.password.value|default_if_none:'' }}">
</div>
<button type="submit">Login</button>
</form>
</div>
</div>
{% endblock %}
{SublimeText} templates/signup.html
{% extends 'welcome.html' %}
{% block logform %}
{% include "navbar_signup.html" %}
<div id="s-content">
<div>
<form method="POST" class="post-form">
{% csrf_token %}
{% include "form_errors.html" %}
<div>
<label for="username">User-ID</label><br>
<input type="text" name="username" id="username"
value="{{ form.username.value|default_if_none:'' }}">
</div>
<div>
<label for="password1">Password</label><br>
<input type="password" name="password1" id="password1"
value="{{ form.password1.value|default_if_none:'' }}">
</div>
<div>
<label for="password2">Password Confirm</label><br>
<input type="password" name="password2" id="password2"
value="{{ form.password2.value|default_if_none:'' }}">
</div>
<div>
<label for="email">E-mail</label><br>
<input type="text" name="email" id="email"
value="{{ form.email.value|default_if_none:'' }}">
</div>
<a href="{% url 'signup_waiting' %}"><button type="submit">Create</button></a>
</form>
</div>
</div>
{% endblock %}
{SublimeText} templates/signup_waiting.html
{% extends 'welcome.html' %}
{% block logform %}
<div id="s-content">
<h3>{{ user.username }}님 반갑습니다~^^</h3>
<h3>{{ user.email }}로 관리자 승인 여부 확인 후 회신 예정입니다.</h3>
</div>
{% endblock %}
{SublimeText} templates/form_errors.html
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ field.label }}</strong>
{{ error }}
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error }}</strong>
</div>
{% endfor %}
{% endif %}
{SublimeText} templates/warning.html
<html>
Warning!!!
</html>
- template : route(navbar)
{SublimeText} templates/navbar_login.html
<nav class="nav_sub" style="color: white; font-size: 20px">
<ul>
<li>Login</li>
</ul>
</nav>
{SublimeText} templates/navbar_main.html
<nav class="nav_main">
<ul>
<li><a href="{% url 'index_sales' %}">영업관리</a></li>
<li><a href="{% url 'index_production' %}">생산관리</a></li>
<li><a href="#">구매관리</a></li>
<li><a href="#">품질관리</a></li>
<li><a href="#">원가관리</a></li>
<li><a href="#">인사관리</a></li>
<li><a href="#">회계관리</a></li>
<li><a href="#">무역관리</a></li>
<li><a href="#">경영관리</a></li>
</ul>
</nav>
{SublimeText} templates/navbar_new.html
<nav class="nav_sub">
<ul>
<li><a href="./new/">새글쓰기</a></li>
</ul>
</nav>
{SublimeText} templates/navbar_notice.html
<nav class="nav_sub" style="color: white; font-size: 18px">
<ul>
<li>Notice</li>
{% if user.is_superuser %}
<a href="{% url 'notice_new' %}"><li>새글쓰기</li></a>
{% endif %}
</ul>
</nav>
{SublimeText} templates/navbar_production.html
<nav class="nav_tree">
<ul>
<li><a href="#">수주조회</a></li>
<li><a href="#">재고조회</a></li>
<li><a href="#">BOM조회</a></li>
<li><a href="#">생산조회</a></li>
<li><a href="#">공정조회</a></li>
<li><a href="#">검사조회</a></li>
<li><a href="#">불량조회</a></li>
<li><a href="#">자재발주</a></li>
<li><a href="#">외주관리</a></li>
<li><a href="#">외주발주</a></li>
</ul>
</nav>
{SublimeText} templates/navbar_sales.html
<nav class="nav_tree">
<ul>
<li><a href="#">재고관리</a></li>
<li><a href="#">수주관리</a></li>
<li><a href="#">출하관리</a></li>
<li><a href="#">매출현황</a></li>
<li><a href="#">이익현황</a></li>
<li><a href="#">거래처구분</a></li>
<li><a href="#">제품구분</a></li>
<li><a href="#">제품이동내역</a></li>
<li><a href="#">정산</a></li>
</ul>
</nav>
{SublimeText} templates/navbar_signup.html
<nav class="nav_sub" style="color: white; font-size: 20px">
<ul>
<li>Sign-Up</li>
</ul>
</nav>
{SublimeText} templates/navbar_sub.html
<nav class="nav_sub">
<ul>
<li><a href="./edit/">수정</a></li>
<li><a href="./delete/">삭제</a></li>
</ul>
</nav>
- templates : home
{SublimeText} home/templates/home_welcome.html
{% extends 'base.html' %}
<!--navbar_top -->
{% block navbar_top %}
{% include "navbar_main.html" %}
{% endblock %}
<!-- Main block -->
{% block content1 %}
<h2>{{ user.username }}님 반갑습니다.</h2>
<table>
<thead>
<tr>
<td><B>사번</B></td>
<td><B>결재함</B></td>
<td><B>일정보기</B></td>
<td><B>잔여휴가</B></td>
</tr>
</thead>
<tbody>
<tr>
<td>staff_num</a></td>
<td><a href="#">approval_count</a></td>
<td><a href="#">schedule_count</a></td>
<td><a href="#">dayoff_count</a></td>
</tr>
</tbody>
</table>
{% endblock %}
<!-- End Main block -->
<!--navbar_sub -->
{% block navbar_sub %}
{% include "navbar_notice.html" %}
{% endblock %}
<!-- Sub block -->
{% block content2 %}
<h2>공지사항</h2>
<table>
<thead>
<tr>
<td><B>No.</B></td>
<td><B>작성자</B></td>
<td><B>제목</B></td>
<td><B>작성일</B></td>
<td><B>조회수</B></td>
</tr>
</thead>
<tbody>
{% for notice in notices %}
<tr>
<td>{{ notice.notice_id }}</td>
<td>{{ notice.author }}</td>
<td><a href="{% url 'notice' notice.pk %}">{{ notice.title }}</a></td>
<td>{{ notice.created_at }}</td>
<td>{{ notice.hit }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
<!-- End Sub block -->
{SublimeText} home/templates/notice.html
{% extends 'base.html' %}
<!--navbar_top -->
{% block navbar_top %}
{% include "navbar_main.html" %}
{% endblock %}
<!-- Main block -->
{% block content1 %}
<h2>공지사항</h2>
<table>
<thead>
<tr>
<td><B>No.</B></td>
<td><B>작성자</B></td>
<td><B>제목</B></td>
<td><B>작성일</B></td>
<td><B>수정일</B></td>
<td><B>조회수</B></td>
</tr>
</thead>
<tbody>
{% for notice in notices %}
<tr>
<td>{{ notice.notice_id }}</td>
<td>{{ notice.author }}</td>
<td><a href="{% url 'notice' notice.pk %}">{{ notice.title }}</a></td>
<td>{{ notice.created_at }}</td>
<td>{{ notice.updated_at }}</td>
<td>{{ notice.hit }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
<!-- End Main block -->
<!--navbar_sub -->
{% block navbar_sub %}
{% include "navbar_notice.html" %}
{% endblock %}
<!-- Sub block -->
{% block content2 %}
<p style="display:none">{{ notice_view.hit_cnt }}</p>
{% if user.is_superuser %}
<a href="{% url 'notice_edit' notice_view.pk %}"><button type="submit">수정하기</button></a>
<a href="{% url 'notice_delete' notice_view.pk %}"><button type="submit">삭제</button></a>
{% endif %}
<h2>{{ notice_view.title }}</h2>
<p>{{ notice_view.article }}</p>
{% endblock %}
<!-- End Sub block -->
{SublimeText} home/templates/notice_edit.html
{% extends 'base.html' %}
<!--navbar_top -->
{% block navbar_top %}
{% include "navbar_main.html" %}
{% endblock %}
<!-- Main block -->
{% block content1 %}
<h2>공지사항</h2>
<table>
<thead>
<tr>
<td><B>No.</B></td>
<td><B>작성자</B></td>
<td><B>제목</B></td>
<td><B>작성일</B></td>
<td><B>수정일</B></td>
<td><B>조회수</B></td>
</tr>
</thead>
<tbody>
{% for notice in notices %}
<tr>
<td>{{ notice.notice_id }}</td>
<td>{{ notice.author }}</td>
<td><a href="{% url 'notice' notice.pk %}">{{ notice.title }}</a></td>
<td>{{ notice.created_at }}</td>
<td>{{ notice.updated_at }}</td>
<td>{{ notice.hit }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
<!-- End Main block -->
<!--navbar_sub -->
{% block navbar_sub %}
{% include "navbar_notice.html" %}
{% endblock %}
<!-- Sub block -->
{% block content2 %}
<h2>수정하기</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<a href="{% url 'home_welcome' %}"><button type="submit">수정</button></a>
</form>
{% endblock %}
<!-- End Sub block -->
{SublimeText} home/templates/notice_delete.py
{% extends 'base.html' %}
<!--navbar_top -->
{% block navbar_top %}
{% include "navbar_main.html" %}
{% endblock %}
<!-- Main block -->
{% block content1 %}
<h2>공지사항</h2>
<table>
<thead>
<tr>
<td><B>No.</B></td>
<td><B>작성자</B></td>
<td><B>제목</B></td>
<td><B>작성일</B></td>
<td><B>수정일</B></td>
<td><B>조회수</B></td>
</tr>
</thead>
<tbody>
{% for notice in notices %}
<tr>
<td>{{ notice.notice_id }}</td>
<td>{{ notice.author }}</td>
<td><a href="{% url 'notice' notice.pk %}">{{ notice.title }}</a></td>
<td>{{ notice.created_at }}</td>
<td>{{ notice.updated_at }}</td>
<td>{{ notice.hit }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
<!-- End Main block -->
<!--navbar_sub -->
{% block navbar_sub %}
{% include "navbar_notice.html" %}
{% endblock %}
<!-- Sub block -->
{% block content2 %}
<h2>새글작성하기</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<a href="{% url 'home_welcome' %}"><button type="submit">생성</button></a>
</form>
<!-- <h2>{{Notice_view.title}}</h2>
<p>{{Notice_view.article}}</p> -->
{% endblock %}
<!-- End Sub block -->
- css : static/css
{SublimeText} static/css/style_home.css
table {
width: 95%;
border: 1px solid #444444;
border-collapse: collapse;
text-align:center;vertical-align:top
}
thead, tbody {
border: 1px solid #444444;
border-collapse: collapse;
}
input[type="text"] {
margin: 5px;
padding: 5px;
border: solid 2px #bcbcbc;
border-radius: 4px;
}
input[type="password"] {
margin: 5px;
padding: 5px;
border: solid 2px #bcbcbc;
border-radius: 4px;
background-color: #000000;
}
#container {
width: auto;
padding: 5px;
border: 1px solid #bcbcbc;
}
#header {
height: 45px;
padding: 1px;
margin-bottom: 5px;
border: 1px solid #bcbcbc;
display: flex;
align-items: center;
}
.logo {
margin: 5px;
padding: 5px;
}
.h-item {
margin: 5px;
padding: 10px;
}
.search-item {
margin: 5px;
padding: 5px;
display: flex;
}
.nav_main {
height:24px;
background-color: #000000;
display: flex;
align-items: center;
}
.nav_tree {
height:24px;
background-color: #696969;
display: flex;
align-items: center;
}
.nav_sub {
height:18px;
background-color: #808080;
display: flex;
align-items: center;
}
.new_input {
width: 10px;
/* height:18px;
background-color: #808080;
display: flex;
align-items: center;*/
}
nav ul {
padding: 5px;
display: flex;
}
nav li {
display: inline;
padding-left: 20px;
}
nav a {
display: inline-block;
font-size: 18px;
text-transform: uppercase;
text-decoration: none;
color: white;
}
#m-content {
width: auto;
padding: 10px;
margin-top: 5px;
margin-bottom: 5px;
border: 2px solid #000080;
}
#s-content {
width: auto;
padding: 10px;
margin-top: 5px;
margin-bottom: 5px;
border: 2px solid #008080;
}
#footer {
clear: both;
padding-left: 10px;
border: 1px solid #bcbcbc;
}
.tg {border-collapse:collapse;border-spacing:0;}
.tg td{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
overflow:hidden;padding:8px 10px;word-break:normal;}
.tg th{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
font-weight:normal;overflow:hidden;padding:8px 10px;word-break:normal;}
.tg .tg-j4pq{background-color:#efefef;border-color:#000000;text-align:center;vertical-align:top}
.tg .tg-wp8o{border-color:#000000;text-align:center;vertical-align:top}
.tg .tg-jbyd{background-color:#ffffff;border-color:#000000;text-align:center;vertical-align:top}
.tg .tg-ymap{background-color:#ffffff;border-color:#000000;font-family:Arial, Helvetica, sans-serif !important;;font-size:28px;
text-align:center;vertical-align:middle}
.tg .tg-73oq{border-color:#000000;text-align:left;vertical-align:top}
.tg .tg-fm1z{background-color:#f0f0f0;border-color:#000000;text-align:center;vertical-align:top}
.tg .tg-xwyw{border-color:#000000;text-align:center;vertical-align:middle}
'python > django_ERP1' 카테고리의 다른 글
(macOS)[python][django][RaspberryPi] ERP platform - 5 : production (0) | 2021.05.31 |
---|---|
(macOS)[python][django][RaspberryPi] ERP platform - 5 : sales (0) | 2021.05.31 |
(macOS)[python][django][RaspberryPi] ERP platform - 4 (0) | 2021.05.03 |
(macOS)[python][django][RaspberryPi] ERP platform - 3 (0) | 2021.04.23 |
(macOS)[python][django][RaspberryPi] ERP platform - 2 (0) | 2021.04.19 |
- Total
- Today
- Yesterday
- analysis
- arduino
- CSV
- Raspberry Pi
- git
- Django
- 자가격리
- r
- DAQ
- github
- DS18B20
- 코로나19
- COVID-19
- 코로나
- Templates
- Model
- vscode
- Regression
- pyserial
- raspberrypi
- 라즈베리파이
- 확진
- Pandas
- sublime text
- server
- MacOS
- Python
- template
- SSH
- ERP
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |