From cde7a3613e143904a3167065a0df1dce6d17a8a4 Mon Sep 17 00:00:00 2001 From: sayefiqb Date: Wed, 3 May 2023 22:17:08 -0400 Subject: [PATCH] category feature --- blog_project/blog/__init__.py | 3 + blog_project/blog/forms.py | 104 +++++++++--------- blog_project/blog/models.py | 23 +++- blog_project/blog/routes.py | 85 ++++++++++++-- blog_project/blog/templates/detail.html | 9 +- .../blog/templates/detail_category.html | 7 ++ blog_project/blog/templates/home.html | 13 +++ blog_project/blog/templates/inc/navbar.html | 1 + blog_project/blog/templates/new_category.html | 12 ++ blog_project/blog/templates/new_post.html | 6 +- 10 files changed, 198 insertions(+), 65 deletions(-) create mode 100644 blog_project/blog/templates/detail_category.html create mode 100644 blog_project/blog/templates/new_category.html diff --git a/blog_project/blog/__init__.py b/blog_project/blog/__init__.py index 5a9b99b..a17fb1a 100644 --- a/blog_project/blog/__init__.py +++ b/blog_project/blog/__init__.py @@ -8,7 +8,10 @@ app = Flask(__name__) app.config['SECRET_KEY'] = os.urandom(30) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db' +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False + db = SQLAlchemy(app) +# db.create_all() bcrypt = Bcrypt(app) login_manager = LoginManager(app) login_manager.login_view = 'login' diff --git a/blog_project/blog/forms.py b/blog_project/blog/forms.py index 76ff115..8f67e32 100644 --- a/blog_project/blog/forms.py +++ b/blog_project/blog/forms.py @@ -1,53 +1,51 @@ -from flask_wtf import FlaskForm -from wtforms import ( - StringField, - PasswordField, - BooleanField, - SubmitField, - TextAreaField -) -from wtforms.validators import ( - DataRequired, - Length, - Email, - EqualTo, - ValidationError -) - -from .models import User - - -class RegistrationForm(FlaskForm): - username = StringField('user name', validators=[ - DataRequired(), Length(min=4, max=25)]) - email = StringField('user email', validators=[DataRequired(), Email()]) - password = PasswordField('password', validators=[DataRequired()]) - confirm_password = PasswordField('confirm password', validators=[ - DataRequired(), EqualTo('password', message='confirm password error')]) - submit = SubmitField('Register') - - def validate_username(self, username): - user = User.query.filter_by(username=username.data).first() - if user: - raise ValidationError('this user already exist') - - -class LoginForm(FlaskForm): - email = StringField('user email', validators=[DataRequired(), Email()]) - password = PasswordField('password', validators=[DataRequired()]) - remember = BooleanField('remember me') - - -class UpdateProfileForm(FlaskForm): - username = StringField('user name', validators=[DataRequired(), Length(min=4, max=25)]) - password = PasswordField('password', validators=[DataRequired()]) - - -class PostForm(FlaskForm): - title = StringField('title', validators=[DataRequired()]) - content = TextAreaField('content', validators=[DataRequired()]) - -class SearchForm(FlaskForm): - query = StringField('Post Title', validators=[DataRequired()]) - submit = SubmitField('Search') - \ No newline at end of file +from blog import db, login_manager +from datetime import datetime +from flask_login import UserMixin + + +@login_manager.user_loader +def load_user(user_id): + return User.query.get(int(user_id)) + + +class User(db.Model, UserMixin): + id = db.Column(db.Integer, primary_key=True) + username = db.Column(db.String(30), unique=True, nullable=False) + email = db.Column(db.String(60), unique=True, nullable=False) + password = db.Column(db.String(60), nullable=False) + posts = db.relationship('Post', backref='author', lazy=True) + categories = db.relationship('Category', backref='author', lazy=True) + + + def __repr__(self): + return f'{self.__class__.__name__}({self.id}, {self.username})' + + +class Post(db.Model): + id = db.Column(db.Integer, primary_key=True) + title = db.Column(db.String(120), nullable=False) + date = db.Column(db.DateTime, nullable=False, default=datetime.now) + content = db.Column(db.Text, nullable=False) + user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) + + def __repr__(self): + return f'{self.__class__.__name__}({self.id}, {self.title})' + +class Category(db.Model): + id = db.Column(db.Integer, primary_key=True) + category = db.Column(db.String(30), nullable=False) + user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) + + def __repr__(self): + return f'{self.__class__.__name__}({self.id}, {self.category})' + +class PostCategory(db.Model): + id = db.Column(db.Integer, primary_key=True) + post_id = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=False) + category_id = db.Column(db.Integer, db.ForeignKey('category.id'), nullable=False) + + def __repr__(self): + return f'{self.__class__.__name__}({self.id})' + +db.create_all() +db.session.commit() \ No newline at end of file diff --git a/blog_project/blog/models.py b/blog_project/blog/models.py index 35bb197..8f67e32 100644 --- a/blog_project/blog/models.py +++ b/blog_project/blog/models.py @@ -14,6 +14,8 @@ class User(db.Model, UserMixin): email = db.Column(db.String(60), unique=True, nullable=False) password = db.Column(db.String(60), nullable=False) posts = db.relationship('Post', backref='author', lazy=True) + categories = db.relationship('Category', backref='author', lazy=True) + def __repr__(self): return f'{self.__class__.__name__}({self.id}, {self.username})' @@ -27,4 +29,23 @@ class Post(db.Model): user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) def __repr__(self): - return f'{self.__class__.__name__}({self.id}, {self.title})' \ No newline at end of file + return f'{self.__class__.__name__}({self.id}, {self.title})' + +class Category(db.Model): + id = db.Column(db.Integer, primary_key=True) + category = db.Column(db.String(30), nullable=False) + user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) + + def __repr__(self): + return f'{self.__class__.__name__}({self.id}, {self.category})' + +class PostCategory(db.Model): + id = db.Column(db.Integer, primary_key=True) + post_id = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=False) + category_id = db.Column(db.Integer, db.ForeignKey('category.id'), nullable=False) + + def __repr__(self): + return f'{self.__class__.__name__}({self.id})' + +db.create_all() +db.session.commit() \ No newline at end of file diff --git a/blog_project/blog/routes.py b/blog_project/blog/routes.py index 4a5c43c..9d2de6d 100644 --- a/blog_project/blog/routes.py +++ b/blog_project/blog/routes.py @@ -1,21 +1,38 @@ from flask import render_template, redirect, url_for, flash, request, abort from . import app, db, bcrypt -from .forms import RegistrationForm, LoginForm, UpdateProfileForm, PostForm , SearchForm -from .models import User, Post +from .forms import RegistrationForm, LoginForm, UpdateProfileForm, PostForm , CategoryForm, SearchForm +from .models import User, Post, Category, PostCategory from flask_login import login_user, current_user, logout_user, login_required - +from pprint import pprint @app.route('/') def home(): posts = Post.query.all() - return render_template('home.html', posts=posts) + categories = Category.query.all() + return render_template('home.html', posts=posts, categories=categories) @app.route('/post/') def detail(post_id): + print(post_id) post = Post.query.get_or_404(post_id) - return render_template('detail.html', post=post) - + postCategory = PostCategory.query.filter_by(post_id=post_id).all() + pprint(postCategory) + categories = [] + for category in postCategory: + print('here......') + print(category.id) + category_name = Category.query.get(category.category_id) + print(category_name) + categories.append(category_name) + print(categories) + return render_template('detail.html', post=post, categories=categories) + + +@app.route('/category/') +def detail_category(category_id): + category = Category.query.get_or_404(category_id) + return render_template('detail_category.html', category=category) @app.route('/register', methods=['GET', 'POST']) def register(): @@ -82,18 +99,48 @@ def profile(): @login_required def new_post(): form = PostForm() + print('Im here') + if form.validate_on_submit(): post = Post( title=form.title.data, - content=form.title.data, + content=form.content.data, author=current_user ) + # print(form.category.data) db.session.add(post) db.session.commit() - flash('post created') + print('Commited to db') + print(form.category.data) + print('>>>>>>>>>>>>>>>>>>>>.') + createPostCategory(form.title.data,form.category.data) + flash('post created') return redirect(url_for('profile')) + else: + print('Did not validate') return render_template('new_post.html', form=form) +# Create a new category +@app.route('/category/create', methods=['GET', 'POST']) +@login_required +def new_category(): + form = CategoryForm() + if form.validate_on_submit(): + category = Category( + category=form.category.data, + author=current_user + ) + print(form.category.data) + print(current_user) + db.session.add(category) + db.session.commit() + db.session.close() + flash('category created') + return redirect(url_for('profile')) + return render_template('new_category.html', form=form) + + + @app.route('/post//delete') @login_required @@ -138,4 +185,24 @@ def search(): else: flash('No such post has been found!','danger') return render_template('search.html',form=form) - return render_template('search.html', form=form) \ No newline at end of file + return render_template('search.html', form=form) + +def getPostId(title): + posts = Post.query.filter(Post.title.like(f"%{title}%")).all() + pprint(posts) + post_id = posts[0].id + return post_id + +def createPostCategory(title, category_ids): + post_id = getPostId(title) + for id in category_ids: + postCategory = PostCategory( + category_id=id, + post_id=post_id + ) + db.session.add(postCategory) + db.session.commit() + +def getAllCategories(): + categories = Category.query.all() + \ No newline at end of file diff --git a/blog_project/blog/templates/detail.html b/blog_project/blog/templates/detail.html index 9e7fa45..37b93af 100644 --- a/blog_project/blog/templates/detail.html +++ b/blog_project/blog/templates/detail.html @@ -5,5 +5,12 @@

{{ post.title }}

{{ post.author.username }} {{ post.date.strftime('%Y-%m-%d') }}
-

{{ post.content|safe }}

+

{{ post.content }}

+ + {% if categories %} +

Category

+ {% for category in categories %} +

{{ category.category }}

+ {% endfor %} + {% endif %} {% endblock content %} \ No newline at end of file diff --git a/blog_project/blog/templates/detail_category.html b/blog_project/blog/templates/detail_category.html new file mode 100644 index 0000000..97e4088 --- /dev/null +++ b/blog_project/blog/templates/detail_category.html @@ -0,0 +1,7 @@ +{% extends 'base.html' %} +

Category

+{% block content %} +

{{ category.category }}

+ {{ category.author.username }} +
+{% endblock content %} \ No newline at end of file diff --git a/blog_project/blog/templates/home.html b/blog_project/blog/templates/home.html index c1997ce..12957f9 100644 --- a/blog_project/blog/templates/home.html +++ b/blog_project/blog/templates/home.html @@ -3,6 +3,7 @@ {% block content %}

Home Page {{ current_user.username }}

+

Post

{% for post in posts %}
@@ -15,4 +16,16 @@
{{ post.title }}
{% endfor %}
+ + +

Category

+ +
+ {% for category in categories %} +
+
{{ category.category }}
+ Show +
+ {% endfor %} +
{% endblock %} diff --git a/blog_project/blog/templates/inc/navbar.html b/blog_project/blog/templates/inc/navbar.html index 22264d4..d41f9a5 100644 --- a/blog_project/blog/templates/inc/navbar.html +++ b/blog_project/blog/templates/inc/navbar.html @@ -6,6 +6,7 @@ {% if current_user.is_authenticated %} Profile Logout + Category {% else %} Login Register diff --git a/blog_project/blog/templates/new_category.html b/blog_project/blog/templates/new_category.html new file mode 100644 index 0000000..3716e3b --- /dev/null +++ b/blog_project/blog/templates/new_category.html @@ -0,0 +1,12 @@ +{% extends 'base.html' %} + +{% block content %} +
+ {{ form.csrf_token }} + + {{ form.category.label}} + {{ form.category}} + + +
+{% endblock content %} \ No newline at end of file diff --git a/blog_project/blog/templates/new_post.html b/blog_project/blog/templates/new_post.html index 5cf5700..4b07f91 100644 --- a/blog_project/blog/templates/new_post.html +++ b/blog_project/blog/templates/new_post.html @@ -10,6 +10,10 @@ {{ form.content.label }} {{ form.content }} - + {{ form.category.label }} + {{ form.category}} + + + {% endblock content %} \ No newline at end of file