Skip to content

Commit 75f909c

Browse files
committed
Posts model, view, orm 적용
1 parent 6274f60 commit 75f909c

10 files changed

Lines changed: 220 additions & 9 deletions

File tree

app/__init__.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from flask import Flask
66
from app.api.database import DB, MA
7+
from app.api import REST_API
78
from app.constants import SQLALCHEMY_DATABASE_URI_FORMAT
89

910

@@ -17,11 +18,7 @@ def create_app()->(Flask):
1718
app.config['DEBUG'] = True
1819

1920
DB.init_app(app)
21+
REST_API.init_app(app)
2022
MA.init_app(app)
21-
22-
@app.route('/')
23-
def root():
24-
""" main page """
25-
return "Hello World!"
26-
23+
2724
return app

app/api/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
"""
2+
API config file
3+
"""
4+
5+
from flask_restplus import Api
6+
from app.users.views import API as users_api
7+
from app.posts.views import API as posts_api
8+
9+
REST_API = Api()
10+
11+
REST_API.add_namespace(users_api, '/user')
12+
REST_API.add_namespace(posts_api, '/post')

app/posts/__init__.py

Whitespace-only changes.

app/posts/models.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""
2+
Posts model file
3+
"""
4+
5+
from app.api.database import DB, MA
6+
from marshmallow import Schema, fields, validate
7+
from app.users.models import Users, UsersSchema
8+
from sqlalchemy.sql import text
9+
10+
class Posts(DB.Model):
11+
__tablename__ = 'posts'
12+
__table_args__ = {'mysql_collate': 'utf8_general_ci'}
13+
14+
id = DB.Column(DB.Integer, primary_key=True)
15+
author_id = DB.Column(DB.String(255), DB.ForeignKey(Users.user_id))
16+
title = DB.Column(DB.String(512), nullable=False)
17+
body = DB.Column(DB.String(1024), nullable=False)
18+
author = DB.relationship('Users', uselist=False)
19+
created = DB.Column(DB.TIMESTAMP, server_default=text("CURRENT_TIMESTAMP"), nullable=False)
20+
21+
def __init__(self, author_id, title, body):
22+
self.author_id = author_id
23+
self.title = title
24+
self.body = body
25+
26+
class PostsSchema(MA.Schema):
27+
not_blank = validate.Length(min=1, error='Field cannot be blank')
28+
id = fields.Integer()
29+
author_id = fields.String(validate=not_blank)
30+
title = fields.String(validate=not_blank)
31+
body = fields.String(validate=not_blank)
32+
author = fields.Nested(UsersSchema)
33+
created = fields.String(validate=not_blank)

app/posts/views.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
"""
2+
Posts view file
3+
"""
4+
5+
from flask_restplus import Namespace, Resource, reqparse, fields
6+
from flask import jsonify, make_response
7+
from http import HTTPStatus
8+
from sqlalchemy.exc import SQLAlchemyError
9+
from app.posts.models import Posts, PostsSchema
10+
from app.users.models import Users, UsersSchema
11+
from app.api.database import DB
12+
13+
API = Namespace('Posts', description="Post's REST API")
14+
POSTS_SCHEMA = PostsSchema()
15+
16+
@API.route('s')
17+
class Post(Resource):
18+
parser = reqparse.RequestParser()
19+
parser.add_argument('author_id', required=True, type=str, help="Post's author ID", location='json')
20+
parser.add_argument('title', required=True, type=str, help="Post's title", location='json')
21+
parser.add_argument('body', required=True, type=str, help="Post's body", location='json')
22+
23+
post_field = API.model('Post', {
24+
'author_id': fields.String,
25+
'title': fields.String,
26+
'body': fields.String
27+
})
28+
29+
@API.doc('get')
30+
def get(self):
31+
try:
32+
posts = Posts.query.all()
33+
body = jsonify(POSTS_SCHEMA.dump(posts, many=True).data)
34+
code = HTTPStatus.OK
35+
except SQLAlchemyError as err:
36+
body = jsonify({'message' : str(err)})
37+
code = HTTPStatus.INTERNAL_SERVER_ERROR
38+
return make_response(body, code.value)
39+
40+
@API.expect(post_field)
41+
@API.doc('post')
42+
def post(self):
43+
args_ = self.parser.parse_args()
44+
post = Posts(author_id=args_['author_id'], title=args_['title'], body=args_['body'])
45+
try:
46+
DB.session.add(post)
47+
DB.session.commit()
48+
body = jsonify({'post', POSTS_SCHEMA.dump(post).data})
49+
code = HTTPStatus.OK
50+
except SQLAlchemyError as err:
51+
body = jsonify({'message' : str(err)})
52+
code = HTTPStatus.INTERNAL_SERVER_ERROR
53+
return make_response(body, code.value)
54+
55+
@API.route('/<int:reqno>')
56+
class PostItem(Resource):
57+
def get(self, reqno):
58+
try:
59+
post = DB.session.query(Posts).outerjoin(
60+
Users, Users.user_id == Posts.author_id).filter(Posts.id==reqno).first()
61+
body = jsonify({'post' : POSTS_SCHEMA.dump(post).data})
62+
code = HTTPStatus.OK
63+
except SQLAlchemyError as err:
64+
body = jsonify({'message' : str(err)})
65+
code = HTTPStatus.INTERNAL_SERVER_ERROR
66+
return make_response(body, code.value)

app/tests/__init__.py

Whitespace-only changes.

app/users/views.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""
2+
User views file
3+
"""
4+
from http import HTTPStatus
5+
from flask import jsonify, make_response
6+
from sqlalchemy.exc import SQLAlchemyError
7+
from flask_restplus import Namespace, Resource, reqparse, fields
8+
from app.users.models import Users, UsersSchema
9+
from app.api.database import DB
10+
11+
API = Namespace('Users', description="User's RESTPlus - API")
12+
USERS_SCHEMA = UsersSchema()
13+
14+
@API.route('s')
15+
class UsersAuth(Resource):
16+
parser = reqparse.RequestParser()
17+
parser.add_argument('user_id', required=True, type=str, help="User's ID", location='json')
18+
parser.add_argument('user_password', required=True, type=str, help="User's PW", location='json')
19+
parser.add_argument('user_email', required=True, type=str, help="User's Email", location='json')
20+
21+
users_field = API.model('Sign up', {
22+
'user_id' : fields.String,
23+
'user_password' : fields.String,
24+
'user_email' : fields.String
25+
})
26+
27+
@API.doc('post')
28+
@API.expect(users_field)
29+
def post(self):
30+
args_ = self.parser.parse_args()
31+
user = Users(args_['user_id'], args_['user_password'], args_['user_email'])
32+
try:
33+
DB.session.add(user)
34+
DB.session.commit()
35+
body = jsonify({'users' : USERS_SCHEMA.dump(user).data})
36+
code = HTTPStatus.OK
37+
except SQLAlchemyError as err:
38+
DB.session.rollback()
39+
body = jsonify({'message' : str(err)})
40+
code = HTTPStatus.INTERNAL_SERVER_ERROR
41+
return make_response(body, code.value)
42+
43+
@API.route('/auth')
44+
class UserAuth(Resource):
45+
parser = reqparse.RequestParser()
46+
parser.add_argument('user_id', required=True, type=str, help="User's ID", location='json')
47+
parser.add_argument('user_password', required=True, type=str, help="User's PW", location='json')
48+
49+
user_login_field = API.model('Sign in', {
50+
'user_id' : fields.String,
51+
'user_password' : fields.String
52+
})
53+
54+
@API.doc('post')
55+
@API.expect(user_login_field)
56+
def post(self):
57+
args_ = self.parser.parse_args()
58+
try:
59+
user = Users.query.filter(Users.user_id == args_['user_id']).first()
60+
body = jsonify({'user_id' : user.user_id})
61+
code = HTTPStatus.OK
62+
except SQLAlchemyError as err:
63+
body = jsonify({'message' : str(err)})
64+
code = HTTPStatus.INTERNAL_SERVER_ERROR
65+
return make_response(body, code.value)

manage.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from app import create_app
88
from app.api.database import DB
99
from app.users.models import Users, UsersSchema
10+
from app.posts.models import Posts, PostsSchema
1011

1112
APP = create_app()
1213
MANAGER = Manager(APP)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""empty message
2+
3+
Revision ID: bb32b366dab2
4+
Revises: d8019933f2c3
5+
Create Date: 2019-07-23 15:07:27.216578
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
11+
12+
# revision identifiers, used by Alembic.
13+
revision = 'bb32b366dab2'
14+
down_revision = 'd8019933f2c3'
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
# ### commands auto generated by Alembic - please adjust! ###
21+
op.create_table('posts',
22+
sa.Column('id', sa.Integer(), nullable=False),
23+
sa.Column('author_id', sa.String(length=255), nullable=True),
24+
sa.Column('title', sa.String(length=512), nullable=False),
25+
sa.Column('body', sa.String(length=1024), nullable=False),
26+
sa.Column('created', sa.TIMESTAMP(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
27+
sa.ForeignKeyConstraint(['author_id'], ['users.user_id'], ),
28+
sa.PrimaryKeyConstraint('id'),
29+
mysql_collate='utf8_general_ci'
30+
)
31+
# ### end Alembic commands ###
32+
33+
34+
def downgrade():
35+
# ### commands auto generated by Alembic - please adjust! ###
36+
op.drop_table('posts')
37+
# ### end Alembic commands ###
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
"""empty message
22
3-
Revision ID: 5ceec2627296
3+
Revision ID: d8019933f2c3
44
Revises:
5-
Create Date: 2019-07-23 10:16:27.384161
5+
Create Date: 2019-07-23 12:06:26.634913
66
77
"""
88
from alembic import op
99
import sqlalchemy as sa
1010

1111

1212
# revision identifiers, used by Alembic.
13-
revision = '5ceec2627296'
13+
revision = 'd8019933f2c3'
1414
down_revision = None
1515
branch_labels = None
1616
depends_on = None

0 commit comments

Comments
 (0)