0. 기본설정
경로
c:\projects\flask\security\templates\syslog
index.html에 내용 붙이기
(d:\jyb\syslog내용.txt 참고)
후 구조 정리해주기
c:\projects\flask\security\templates\sensor에도 동일하게 구조 정리
c:\projects\flask\security\templates
base.html에서
components에 경로 지정해주기
{{url_for('syslog.index')}}
{{url_for('sensor.index')}}
1. 로그인 기능 만들기
ci4 > mvc (model, view, controller)
flask, django > mtv (model)
c:\projects\flask\security
models.py 생성 #설계도 역할------------
기본틀
class User(db.Model):
id=db.Column()
username=db.Column()
password=db.Column()
email=db.Column()
구조정리
from security import db
class User(db.Model):
id=db.Column(db.Integer,primary_key=True) #숫자
username=db.Column(db.String(150),unique=True,nullable=False) #아이디
password=db.Column(db.String(200),nullable=False) #비밀번호
email=db.Column(db.String(120),unique=True,nullable=False)
class Syslog(db.Model):
id=db.Column(db.Integer,primary_key=True) #숫자
recievedat=db.Column(db.String(150),nullable=False)
fromhost=db.Column(db.String(200),nullable=False)
message=db.Column(db.String(120),nullable=False)
class Sensor(db.Model):
id=db.Column(db.Integer,primary_key=True) #숫자
distance=db.Column(db.String(150),nullable=False)
temperature=db.Column(db.String(200),nullable=False)
humidity=db.Column(db.String(120),nullable=False)
regdate=db.Column*db.DateTime(120),nullable=True)
2. 데이터베이스 연결하기
로그 데이터 : 192.168.0.118 (우분투 > syslog)
센서 데이터 : 192.168.0.98 (Raspbian GNU ; 라즈베리파이)
c:\projects\flask\security
__init__.py에 추가
from flask import Flask
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
db= SQLAlchemy()
migrate = Migrate()
def create_app():
#ORM(Object Relational Mapping) (데이터베이스 연결)
#sql > insert,delete,update,select 데이터베이스의 데이터를 처리할 수 있는 기술
db.init_app(app)
migrate.init_app(app,db)
rom . import models
SQLALchemy()
AndoridServer에 동일하게 존재
cmd
pip install Flask-Migrate
flask run
c:\projects\flask\config
default.py
development.py 이해하기
새로운 cmd
set APP_CONFIG_FILE=C:\projects\flask\config\development.py
mysite
#데이터베이스 관련 명령어
flask db init #초기화
flask db migrate #모델로 새로 생성하거나 변경할 때 사용
=>security.db 생성
flask db upgrade #실제 데이터베이스에 적용
=> db browser for sqlite 프로그램 사용
security.db 열기
테이블 생성 확인가능
#데이터베이스에 접근
flask shell
from security.models import User
(User.query.all() 해보면 [] 확인 가능)
#유저 추가
from datetime import datetime
from security import db
u = User(username='admin',password='123456',email='test@test.com')
db.session.add(u)
db.session.commit()
=> [< User 1>] 확인
=> db sqlite 데이터베이스 탐색란에서도 확인가능
#검색 시
User.query.all() #확인
User.query.filter(User.id==1).all()
User.query.get(1)
User.query.filter(User.username.like("%ad%")).all()
수정
db.session.commit()
삭제
db.session.delete(u)
db.session.commit()
결론
mysql에서 배운 DML(select, update, delete, insert)문을 몰라도 사용할 수 있다.
로그인 페이지 만들기
c:\projects\flask\security\templates\auth
login.html
로그인 처리 부분에 추가
< form class="user" method="post">
#{{form.csrf_token}}
< div class="form-group">
< input type="text" class="form-control form-control-user"
id="username" name="username"
aria-describedby="계정 입력"
placeholder="계정 입력">
< /div>
cmd
flask run
jinja2.exceptions.UndefinedError: 'form' is undefined 에러시
forms.py 만들어주기
c:\projects\flask\security
forms.py
from flask_wtf import FlaskForm
from wtforms import StringField,TextAreaField, PasswordField
from wtforms.validators import DataRequired,Length
class UserLoginForm(FlaskForm):
username=StringField('아이디',validators=[DataRequired(),Length(min=3,max=15)])
password=PasswordField('비밀번호',validators=[DataRequired()])
=> 유효성 검사
빈칸 안됨, 아이디 최소 3자리, 최대 15자리
c:\projects\flask\security\views
auth.py에 추가
from flask import Blueprint,render_template
from flask import url_for
from flask import flash
from flask import request
from flask import session
from werzeug.security import generate_password_hash
from werzeug.security import check_password_hash
from werkzeug.utils import redirect
from security import db
from security.forms import UserLoginForm
bp = Blueprint('auth',__name__,url_prefix='/auth')
@bp.route('/login',methods=('GET', 'POST'))
def login():
form = UserLoginForm()
if request.method== 'POST':
return render_template('auth/login.html')
else:
return render_template('auth/login.html')
cmd
#form을 쓰기 위해 필요
pip install Flask-WTF
기본설치
pip install flask
pip install Flask-Migrate
pip install Flask-WTF
pip install email_validator
c:\projects\flask\security\templates
form_errors.html에 추가
{% for field, errors in form.errors.items() %}
< div>
{{form[field].label}}
< /vid>
{%endfor%}
{% for message in get_flashed_messages() %}
< div>
{{message}}
< /div>
{%endfor%}
***
이해하기
실질적 내용(코딩)
c:\projects\flask\security\view
auth.py
main.py
sensor.py
syslog.py
그외 전부 셋팅 파일
***
3. 로그인 시 특정 페이지를 보이지 않도록 설정
c:\projects\flask\security\templates
base.py
기본틀
{% if g.user %}
{% else %}
{% endif %}
#로그아웃 숨기기 {% if g.user %}
< div class="dropdown-divider">
< a class="dropdown-item" href="#" data-toggle="modal" data-target="#logoutModal">
< i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400">
Logout
< /a>
{% endif %}
#목차 숨기기
{% if g.user %}
< a class="collapse-item" href="{{url_for('syslog.index')}}">syslog
< a class="collapse-item" href="{{url_for('sensor.index')}}">sensor
{% endif %}
django는 로그인 페이지를 따로 만들지 않아도 기본값으로 설정되어있다.
c:\projects\flask\security\views\
auth.py에 추가
from flask import g
#로그인한 사용자 정보를 조회하는 기능 구현
@bp.before_app_request
def load_logged_in_user():
username = session.get('username')
if username is None:
g.user = None
else:
g.user = User.query.get(username)
auth.py의 username을 user_id로 변경
c:\projects\flask\config
development.py
#SQLALCHEMY_DATABASE_URI='sqlite:///{}'.format(os.path.join(BASE_DIR,'security.db'))
SQLALCHEMY_DATABASE_URI='mysql+pymysql://master:123456@192.168.0.98/your_database'
#app.config('SQLALCHEMY_DATABASE_URI'] = 'mysql+pmysql://master:123456@192.168.0.98/your_database'
pip install pymysql
flask migration 폴더삭제
flask db init
flask db migrate
flask db upgrade
workbench
{{sensor}}
#센서 페이지 로그인 후 보이도록 설정
c:\projects\flask\security\views
sensor.py
datas = Sensor.query.order_by(Sensor.regdate.desc())추가
c:\projects\flask\security\templates\sensor
index.html추가
{% if sensor %} {% for data in sensor%} < tr {% if data.distance | float < 500 %}style="background-color: red; color: white;"{% endif %}>
< td>{{ data.id }}< /td>
< td>{{ data.distance }}< /td>
< td>{{ data.temperature }}< /td>
< td>{{ data.humidity }}< /td>
< td>{{ data.regdate }}< /td>
< /tr> {% endfor %}
{% else %}
< tr>
< td colspan=5>데이터 없음< /td>
< /tr>
{% endif %}
페이징!!
c:\projects\flask\security\views
sensor.py
from flask import Blueprint,render_template, request
from security.models import Sensor
bp = Blueprint('sensor',__name__,url_prefix='/sensor')
@bp.route('/')
def index():
page = request.args.get('page', 1, type=int)
per_page = 10
datas = Sensor.query.order_by(Sensor.regdate.desc()).paginate(page=page, per_page=per_page, error_out=True)
return render_template('sensor/index.html',sensor=datas)
c:\projects\flask\security\templates\sensor
index.html추가
< !-- 페이지네이션 -->
< div class="pagination">
{% if sensor.has_prev %}
< a href="{{ url_for('sensor.index', page=sensor.prev_num) }}">이전< /a>
{% endif %}
< span>페이지 {{ sensor.page }} / {{ sensor.pages }}< /span>
{% if sensor.has_next %}
< a href="{{ url_for('sensor.index', page=sensor.next_num) }}">다음< /a>
{% endif %}
< /div>