diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..8550006
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..df5f35d
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/dictionaries/.xml b/.idea/dictionaries/.xml
new file mode 100644
index 0000000..291ce5b
--- /dev/null
+++ b/.idea/dictionaries/.xml
@@ -0,0 +1,7 @@
+
+
+
+ sqlalchemy
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..de8d7f4
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/helloworld_web.iml b/.idea/helloworld_web.iml
index 858c4d5..ca5e422 100644
--- a/.idea/helloworld_web.iml
+++ b/.idea/helloworld_web.iml
@@ -4,7 +4,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index be8870e..b228a21 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/app/__init__.py b/app/__init__.py
new file mode 100644
index 0000000..29ce935
--- /dev/null
+++ b/app/__init__.py
@@ -0,0 +1,21 @@
+from flask import Flask
+from flask_migrate import Migrate, MigrateCommand
+from flask_sqlalchemy import SQLAlchemy
+from flask_script import Manager, Command, Shell
+from flask_login import LoginManager
+import os, config
+
+# создание экземпляра приложения
+app = Flask(__name__)
+app.config.from_object(os.environ.get('FLASK_ENV') or 'config.DevelopementConfig')
+
+# инициализирует расширения
+db = SQLAlchemy(app)
+migrate = Migrate(app, db)
+login_manager = LoginManager(app)
+login_manager.login_view = 'login'
+
+# import views
+from . import views
+# from . import forum_views
+# from . import admin_views
diff --git a/forms.py b/app/forms.py
similarity index 100%
rename from forms.py
rename to app/forms.py
diff --git a/app/models.py b/app/models.py
new file mode 100644
index 0000000..12bd3ad
--- /dev/null
+++ b/app/models.py
@@ -0,0 +1,85 @@
+from app import db, login_manager
+from datetime import datetime
+from flask_login import (LoginManager, UserMixin, login_required,
+ login_user, current_user, logout_user)
+from werkzeug.security import generate_password_hash, check_password_hash
+
+
+class Category(db.Model):
+ __tablename__ = 'categories'
+ id = db.Column(db.Integer(), primary_key=True)
+ name = db.Column(db.String(255), nullable=False)
+ slug = db.Column(db.String(255), nullable=False)
+ created_on = db.Column(db.DateTime(), default=datetime.utcnow)
+ posts = db.relationship('Post', backref='category')
+
+ def __repr__(self):
+ return "<{}:{}>".format(id, self.name)
+
+
+class Post(db.Model):
+ __tablename__ = 'posts'
+ id = db.Column(db.Integer(), primary_key=True)
+ title = db.Column(db.String(255), nullable=False)
+ slug = db.Column(db.String(255), nullable=False)
+ content = db.Column(db.Text(), nullable=False)
+ created_on = db.Column(db.DateTime(), default=datetime.utcnow)
+ updated_on = db.Column(db.DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
+ category_id = db.Column(db.Integer(), db.ForeignKey('categories.id'))
+
+ def __repr__(self):
+ return "<{}:{}>".format(self.id, self.title[:10])
+
+
+post_tags = db.Table('post_tags',
+ db.Column('post_id', db.Integer, db.ForeignKey('posts.id')),
+ db.Column('tag_id', db.Integer, db.ForeignKey('tags.id'))
+ )
+
+
+class Tag(db.Model):
+ __tablename__ = 'tags'
+ id = db.Column(db.Integer(), primary_key=True)
+ name = db.Column(db.String(255), nullable=False)
+ slug = db.Column(db.String(255), nullable=False)
+ created_on = db.Column(db.DateTime(), default=datetime.utcnow)
+ posts = db.relationship('Post', secondary=post_tags, backref='tags')
+
+ def __repr__(self):
+ return "<{}:{}>".format(id, self.name)
+
+
+class Feedback(db.Model):
+ __tablename__ = 'feedbacks'
+ id = db.Column(db.Integer(), primary_key=True)
+ name = db.Column(db.String(1000), nullable=False)
+ email = db.Column(db.String(100), nullable=False)
+ message = db.Column(db.Text(), nullable=False)
+ created_on = db.Column(db.DateTime(), default=datetime.utcnow)
+
+ def __repr__(self):
+ return "<{}:{}>".format(self.id, self.name)
+
+
+class User(db.Model, UserMixin):
+ __tablename__ = 'users'
+ id = db.Column(db.Integer(), primary_key=True)
+ name = db.Column(db.String(100))
+ username = db.Column(db.String(50), nullable=False, unique=True)
+ email = db.Column(db.String(100), nullable=False, unique=True)
+ password_hash = db.Column(db.String(100), nullable=False)
+ created_on = db.Column(db.DateTime(), default=datetime.utcnow)
+ updated_on = db.Column(db.DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
+
+ def __repr__(self):
+ return "<{}:{}>".format(self.id, self.username)
+
+ def set_password(self, password):
+ self.password_hash = generate_password_hash(password)
+
+ def check_password(self, password):
+ return check_password_hash(self.password_hash, password)
+
+@login_manager.user_loader
+def load_user(user_id):
+ return db.session.query(User).get(user_id)
diff --git a/templates/admin.html b/app/templates/admin.html
similarity index 100%
rename from templates/admin.html
rename to app/templates/admin.html
diff --git a/templates/contact.html b/app/templates/contact.html
similarity index 100%
rename from templates/contact.html
rename to app/templates/contact.html
diff --git a/templates/index.html b/app/templates/index.html
similarity index 100%
rename from templates/index.html
rename to app/templates/index.html
diff --git a/templates/login.html b/app/templates/login.html
similarity index 100%
rename from templates/login.html
rename to app/templates/login.html
diff --git a/app/views.py b/app/views.py
new file mode 100644
index 0000000..42a88e5
--- /dev/null
+++ b/app/views.py
@@ -0,0 +1,62 @@
+from app import app
+from flask import render_template, request, redirect, url_for, flash
+from flask_login import login_required, login_user,current_user, logout_user
+from .models import User, Post, Category, Feedback, db
+from .forms import ContactForm, LoginForm
+
+
+@app.route('/admin/')
+@login_required
+def admin():
+ return render_template('admin.html')
+
+
+@app.route('/')
+def index():
+ return render_template('index.html')
+
+
+@app.route('/login/', methods=['post', 'get'])
+def login():
+ if current_user.is_authenticated:
+ return redirect(url_for('admin'))
+ form = LoginForm()
+ if form.validate_on_submit():
+ user = db.session.query(User).filter(User.username == form.username.data).first()
+ if user and user.check_password(form.password.data):
+ login_user(user, remember=form.remember.data)
+ nextpage = request.args.get('next', url_for('admin'))
+ return redirect(nextpage)
+ else:
+ flash("Invalid username/password", 'error')
+ return render_template('login.html', form=form)
+
+
+@app.route('/logout/')
+@login_required
+def logout():
+ logout_user()
+ flash("You have been logged out.")
+ return redirect(url_for('login'))
+
+
+@app.route('/contact/', methods=['get', 'post'])
+def contact():
+ form = ContactForm()
+ if form.validate_on_submit():
+ name = form.name.data
+ email = form.email.data
+ message = form.message.data
+ print(name)
+ print(email)
+ print(message)
+ # здесь логика базы данных
+ feedback = Feedback(name=name, email=email, message=message)
+ db.session.add(feedback)
+ db.session.commit()
+
+ print("\nData received. Now redirecting ...")
+ flash("Message Received", "success")
+ return redirect(url_for('contact'))
+
+ return render_template('contact.html', form=form)
diff --git a/config.py b/config.py
new file mode 100644
index 0000000..db1c4a8
--- /dev/null
+++ b/config.py
@@ -0,0 +1,23 @@
+import os
+
+app_dir = os.path.abspath(os.path.dirname(__file__))
+
+
+class BaseConfig:
+ SECRET_KEY = os.environ.get('SECRET_KEY') or '0d6e368e-bd0c-11ea-921d-9342d47f60ca'
+ SQLALCHEMY_TRACK_MODIFICATIONS = False
+
+
+class DevelopementConfig(BaseConfig):
+ DEBUG = True
+ SQLALCHEMY_DATABASE_URI = 'sqlite:///db.sqlite'
+
+
+class TestingConfig(BaseConfig):
+ DEBUG = True
+ SQLALCHEMY_DATABASE_URI = 'sqlite:///db.sqlite'
+
+
+class ProductionConfig(BaseConfig):
+ DEBUG = False
+ SQLALCHEMY_DATABASE_URI = 'sqlite:///db.sqlite'
diff --git a/main.py b/main.py
deleted file mode 100644
index 9b1b5c1..0000000
--- a/main.py
+++ /dev/null
@@ -1,178 +0,0 @@
-import flask
-from flask import Flask, request, current_app, url_for, render_template, flash, redirect
-from werkzeug.security import generate_password_hash, check_password_hash
-from flask_script import Manager, Shell
-from flask_migrate import Migrate, MigrateCommand
-from flask_login import LoginManager, UserMixin, login_required, login_user, current_user, logout_user
-from jinja2 import Template
-from flask_sqlalchemy import SQLAlchemy
-from datetime import datetime
-
-from forms import ContactForm, LoginForm
-
-app = Flask(__name__)
-app.debug = True
-app.config['SECRET_KEY'] = '0d6e368e-bd0c-11ea-921d-9342d47f60ca'
-app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
-app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///db.sqlite"
-db = SQLAlchemy(app)
-login_manager = LoginManager(app)
-login_manager.login_view = 'login'
-migrate = Migrate(app, db)
-manager = Manager(app)
-manager.add_command('db', MigrateCommand)
-
-
-class Category(db.Model):
- __tablename__ = 'categories'
- id = db.Column(db.Integer(), primary_key=True)
- name = db.Column(db.String(255), nullable=False)
- slug = db.Column(db.String(255), nullable=False)
- created_on = db.Column(db.DateTime(), default=datetime.utcnow)
- posts = db.relationship('Post', backref='category')
-
- def __repr__(self):
- return "<{}:{}>".format(id, self.name)
-
-
-class Post(db.Model):
- __tablename__ = 'posts'
- id = db.Column(db.Integer(), primary_key=True)
- title = db.Column(db.String(255), nullable=False)
- slug = db.Column(db.String(255), nullable=False)
- content = db.Column(db.Text(), nullable=False)
- created_on = db.Column(db.DateTime(), default=datetime.utcnow)
- updated_on = db.Column(db.DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
- category_id = db.Column(db.Integer(), db.ForeignKey('categories.id'))
-
- def __repr__(self):
- return "<{}:{}>".format(self.id, self.title[:10])
-
-
-post_tags = db.Table('post_tags',
- db.Column('post_id', db.Integer, db.ForeignKey('posts.id')),
- db.Column('tag_id', db.Integer, db.ForeignKey('tags.id'))
- )
-
-
-class Tag(db.Model):
- __tablename__ = 'tags'
- id = db.Column(db.Integer(), primary_key=True)
- name = db.Column(db.String(255), nullable=False)
- slug = db.Column(db.String(255), nullable=False)
- created_on = db.Column(db.DateTime(), default=datetime.utcnow)
- posts = db.relationship('Post', secondary=post_tags, backref='tags')
-
- def __repr__(self):
- return "<{}:{}>".format(id, self.name)
-
-
-class Feedback(db.Model):
- __tablename__ = 'feedbacks'
- id = db.Column(db.Integer(), primary_key=True)
- name = db.Column(db.String(1000), nullable=False)
- email = db.Column(db.String(100), nullable=False)
- message = db.Column(db.Text(), nullable=False)
- created_on = db.Column(db.DateTime(), default=datetime.utcnow)
-
- def __repr__(self):
- return "<{}:{}>".format(self.id, self.name)
-
-
-class User(db.Model, UserMixin):
- __tablename__ = 'users'
- id = db.Column(db.Integer(), primary_key=True)
- name = db.Column(db.String(100))
- username = db.Column(db.String(50), nullable=False, unique=True)
- email = db.Column(db.String(100), nullable=False, unique=True)
- password_hash = db.Column(db.String(100), nullable=False)
- created_on = db.Column(db.DateTime(), default=datetime.utcnow)
- updated_on = db.Column(db.DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
-
- def __repr__(self):
- return "<{}:{}>".format(self.id, self.username)
-
- def set_password(self, password):
- self.password_hash = generate_password_hash(password)
-
- def check_password(self, password):
- return check_password_hash(self.password_hash, password)
-
-
-@login_manager.user_loader
-def load_user(user_id):
- return db.session.query(User).get(user_id)
-
-
-@app.route('/admin/')
-@login_required
-def admin():
- return render_template('admin.html')
-
-
-@manager.command
-def faker():
- print("Команда для добавления поддельных данных в таблицы")
-
-
-@app.route('/')
-def index():
- return render_template('index.html')
-
-
-@app.route('/login/', methods=['post', 'get'])
-def login():
- if current_user.is_authenticated:
- return redirect(url_for('admin'))
- form = LoginForm()
- if form.validate_on_submit():
- user = db.session.query(User).filter(User.username == form.username.data).first()
- if user and user.check_password(form.password.data):
- login_user(user, remember=form.remember.data)
- nextpage = request.args.get('next', url_for('admin'))
- return redirect(nextpage)
- else:
- flash("Invalid username/password", 'error')
- return render_template('login.html', form=form)
-
-
-@app.route('/logout/')
-@login_required
-def logout():
- logout_user()
- flash("You have been logged out.")
- return redirect(url_for('login'))
-
-@app.route('/contact/', methods=['get', 'post'])
-def contact():
- form = ContactForm()
- if form.validate_on_submit():
- name = form.name.data
- email = form.email.data
- message = form.message.data
- print(name)
- print(email)
- print(message)
- # здесь логика базы данных
- feedback = Feedback(name=name, email=email, message=message)
- db.session.add(feedback)
- db.session.commit()
-
- print("\nData received. Now redirecting ...")
- flash("Message Received", "success")
- return redirect(url_for('contact'))
-
- return render_template('contact.html', form=form)
-
-
-def shell_context():
- import os, sys
- return {'app': app, 'os': os, 'sys': sys, 'flask': flask, 'request': request, 'current_app': current_app,
- 'url_for': url_for, 'Template': Template, 'db': db}
-
-
-manager.add_command("shell", Shell(make_context=shell_context))
-
-if __name__ == "__main__":
- db.init_app(app)
- manager.run()
diff --git a/models.py b/models.py
deleted file mode 100644
index e69de29..0000000
diff --git a/runner.py b/runner.py
new file mode 100644
index 0000000..aae9f44
--- /dev/null
+++ b/runner.py
@@ -0,0 +1,31 @@
+import os
+
+import flask
+from flask import request, current_app, url_for
+from jinja2 import Template
+
+from app import app, db
+from app.models import User, Post, Tag, Category, Feedback
+from flask_script import Manager, Shell
+from flask_migrate import MigrateCommand
+
+manager = Manager(app)
+
+
+@manager.command
+def faker():
+ print("Команда для добавления поддельных данных в таблицы")
+
+
+def shell_context():
+ import sys
+ return {'app': app, 'os': os, 'sys': sys, 'flask': flask, 'request': request, 'current_app': current_app,
+ 'url_for': url_for, 'Template': Template, 'db': db, 'User': User, 'Post': Post, 'Tag': Tag,
+ 'Category': Category, 'Feedback': Feedback}
+
+
+manager.add_command("shell", Shell(make_context=shell_context))
+manager.add_command('db', MigrateCommand)
+
+if __name__ == '__main__':
+ manager.run()