当前位置:网站首页>Flask develops and implements the like comment module of the online question and answer system
Flask develops and implements the like comment module of the online question and answer system
2022-06-11 05:27:00 【Always happy old pea】
Preface
Implement the comment module
Realize the development of answer comment function
from flask import Blueprint, render_template, request, abort, redirect, url_for, flash, jsonify
from flask_login import login_required, current_user
from models import Question, Answer, AnswerComment, db
from qa.forms import WriteQuestionForm, WriteAnswerForm
qa = Blueprint('qa', __name__,
template_folder='templates',
static_folder='../assets')
@qa.route('/')
def index():
""" home page Answer list """
per_page = 20 # Size of data per page
page = int(request.args.get('page', 1))
page_data = Answer.query.filter_by(is_valid=True).paginate(
page=page, per_page=per_page)
return render_template('index.html', page_data=page_data)
@qa.route('/follow')
def follow():
""" Focus on List of questions """
per_page = 20 # Size of data per page
page = int(request.args.get('page', 1))
page_data = Question.query.filter_by(is_valid=True).paginate(
page=page, per_page=per_page)
return render_template('follow.html', page_data=page_data)
@qa.route('/qa/list')
def question_list():
""" Query the problem data list
// json
{
'code': 0,
'data': ''
}
"""
try:
per_page = 2 # Size of data per page
page = int(request.args.get('page', 1))
page_data = Question.query.filter_by(is_valid=True).paginate(
page=page, per_page=per_page)
data = render_template('qa_list.html', page_data=page_data)
return {
'code': 0, 'data': data}
except Exception as e:
print(e)
data = ''
return {
'code': 1, 'data': ''}
@qa.route('/write', methods=['GET', 'POST'])
@login_required
def write():
""" Write an article , put questions to """
form = WriteQuestionForm()
if form.validate_on_submit():
try:
que_obj = form.save()
if que_obj:
flash(' Successfully released the problem ', 'success')
return redirect(url_for('qa.index'))
except Exception as e:
print(e)
flash(' Publishing problem failed , Please try again later ', 'danger')
return render_template('write.html', form=form)
@qa.route('/detail/<int:q_id>', methods=['GET', 'POST'])
def detail(q_id):
""" Details of the problem """
# 1. Query question information
question = Question.query.get(q_id)
if not question.is_valid:
abort(404)
# 2. Show the first response
answer = question.answer_list.filter_by(is_valid=True).first()
# Add answer
form = WriteAnswerForm()
if form.validate_on_submit():
try:
if not current_user.is_authenticated:
flash(' Please log in first ', 'danger')
return redirect(url_for('accounts.login'))
form.save(question=question)
flash(' Answer the question successfully ', 'success')
return redirect(url_for('qa.detail', q_id=q_id))
except Exception as e:
print(e)
return render_template('detail.html',
question=question,
answer=answer,
form=form)
@qa.route('/comments/<int:answer_id>', methods=['GET', 'POST'])
def comments(answer_id):
""" Comment on """
answer = Answer.query.get(answer_id)
if request.method == 'POST':
# Add comments
try:
if not current_user.is_authenticated:
result = {
'code': 1, 'message': ' Please log in '}
return jsonify(result), 400
# 1. get data
content = request.form.get('content', '')
# 2. Save to database
question = answer.question
comment_obj = AnswerComment(content=content,
user=current_user,
answer=answer,
question=question
)
db.session.add(comment_obj)
db.session.commit()
return '', 201
except Exception as e:
result = {
'code': 1, 'message': ' The server is busy , Please try again later '}
return jsonify(result), 400
else:
# Get a list of comments
pass
{
% extends 'base_layout.html' %}
{
% block title %}{
{
super() }} - Article details {
% endblock %}
{
% block header %}
<link rel="stylesheet" href="/assets/style/detail.css">
{
% endblock %}
{
% block content %}
<!-- A brief description of the problem -->
<div class="layout-question">
<div class="container">
<div class="row">
<div class="col-md-9">
{
% include 'components/flash_messages.html' %}
<!-- Question tag -->
{
% if question.tags %}
<ul class="que-tag-ls">
{
% for tag in question.tags %}
<li><a href="#">{
{
tag.tag_name }}</a></li>
{
% endfor %}
</ul>
{
% endif %}
<!-- // Question tag -->
<h3>{
{
question.title }}</h3>
<div class="show-desc hidden">
{
{
question.desc|d(' no ', True) }}…
<span class="btn-show-more"> Show all <i class="glyphicon glyphicon-menu-down"></i></span>
</div>
<div class="show-all ">
{
% autoescape false %}
{
{
question.content|safe }}
{
% endautoescape %}
<span class="btn-show-less"> Retract <i class="glyphicon glyphicon-menu-up"></i></span>
</div>
<!-- menu bar -->
<div class="qa-footer">
<div>
<button type="button" class="btn btn-info btn-sm"> Turn off notes </button>
</div>
<div>
<button type="button" class="btn btn-info btn-sm" data-toggle="modal" data-target="#addComment"> Write the answer </button>
</div>
<div class="txt-menu"><i class="glyphicon glyphicon-comment"></i> {
{
question.comment_count }} comments </div>
<div class="txt-menu"><i class="glyphicon glyphicon-send"></i> Share </div>
<div class="txt-menu"><i class="glyphicon glyphicon-flag"></i> report </div>
<div class="txt-menu"></div>
<div class="txt-menu btn-group">
<i class="glyphicon glyphicon-option-horizontal dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false"></i>
<ul class="dropdown-menu">
<li><a href="#"> Not interested in </a></li>
</ul>
</div>
</div>
<!-- // menu bar -->
</div>
<div class="col-md-3">
<div class="que-stats-box">
<!-- Concern -->
<div>
<span> Concern </span>
<strong>{
{
question.follow_count|number_split }}</strong>
</div>
<!-- // Concern -->
<!-- Browsed -->
<div>
<span> Browsed </span>
<strong>{
{
question.view_count|number_split }}</strong>
</div>
<!-- // Browsed -->
</div>
</div>
</div><!-- // row -->
</div>
</div>
<!-- // A brief description of the problem -->
<div class="layout-answer">
<div class="container">
<div class="row">
<div class="col-md-9 left-content">
{
% block link_more %}
<a class="link-more" href="#"> Check all {
{
question.answer_count|number_split }} answer </a>
{
% endblock %}
<!-- Answer the content area -->
{
% if answer %}
<div class="answer-content box-wrap">
<div class="user-info">
<div class="avater">
{
% if answer.user.avatar %}
<img src="{
{ answer.user.avatar }}" alt=" The avatars ">
{
% else %}
<img src="/assets/home/qa/user_head.jpg" alt=" The avatars ">
{
% endif %}
</div>
<div class="desc">
<h4>{
{
answer.user.nickname }}</h4>
<p>{
{
answer.user.profile.maxim }}</p>
</div>
</div>
<div class="answer-stats">5,550 I agree with the answer </div>
<div class="answer-txt">
{
% autoescape false %}
{
{
answer.content|safe }}
{
% endautoescape %}
</div>
<div class="answer-time"> Published on {
{
answer.created_at }}</div>
<!-- At the bottom of the menu -->
<div class="qa-footer">
<div><button type="button" class="btn btn-info btn-sm">
<i class="glyphicon glyphicon-thumbs-up"></i> Agree with {
{
answer.love_count }}</button>
<button type="button" class="btn btn-info btn-sm"><i
class="glyphicon glyphicon-thumbs-down"></i></button>
</div>
<div class="txt-menu"><i class="glyphicon glyphicon-comment"></i> 113 comments </div>
<div class="txt-menu"><i class="glyphicon glyphicon-send"></i> Share </div>
<div class="txt-menu"><i class="glyphicon glyphicon-heart"></i> Collection </div>
<div class="txt-menu"><i class="glyphicon glyphicon-flag"></i> report </div>
<div class="txt-menu"></div>
<div class="txt-menu btn-group">
<i class="glyphicon glyphicon-option-horizontal dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false"></i>
<ul class="dropdown-menu">
<li><a href="#"> Not interested in </a></li>
</ul>
</div>
</div>
<!-- // At the bottom of the menu -->
<!-- Comment box -->
<div class="comment-box box-wrap">
<!-- Statistics and menus -->
<div class="comment-stats">
<div class="title">8 comments </div>
<div class="menu"><i class="glyphicon glyphicon-random"></i> Switch to chronological order </div>
</div>
<!-- // Statistics and menus -->
<!-- Comment list -->
<div class="comment-ls">
<div class="comment-item">
<div class="header">
<div class="user-info">
<img class="avater" src="/assets/home/qa/user_head.jpg" alt="">
<strong class="uname"> The user nickname </strong>
</div>
<div class="time">2 Hours before </div>
</div>
<div class="body">
You can't say that , It is their vision that makes them unacceptable . What China has done now is to make their world outlook collapse [ Laugh with tears ][ Laugh with tears ]
</div>
<div class="footer">
<div><i class="glyphicon glyphicon-thumbs-up"></i> 5</div>
<div><i class="glyphicon glyphicon-share-alt"></i> reply </div>
<div><i class="glyphicon glyphicon-thumbs-down"></i> Step on </div>
<div><i class="glyphicon glyphicon-flag"></i> report </div>
</div>
<!-- Input box -->
<form class="form-horizontal comment-publish">
<input type="text" class="form-control" placeholder=" Write down your comments ...">
<button type="button" class="btn btn-default btn-grey"> Release </button>
</form>
<!-- // Input box -->
</div>
<div class="comment-item">
<div class="header">
<div class="user-info">
<img class="avater" src="/assets/home/qa/user_head.jpg" alt="">
<strong class="uname"> The user nickname </strong>
</div>
<div class="time">2 Hours before </div>
</div>
<div class="body">
You can't say that , It is their vision that makes them unacceptable . What China has done now is to make their world outlook collapse [ Laugh with tears ][ Laugh with tears ]
</div>
<div class="footer">
<div><i class="glyphicon glyphicon-thumbs-up"></i> 5</div>
<div><i class="glyphicon glyphicon-share-alt"></i> reply </div>
<div><i class="glyphicon glyphicon-thumbs-down"></i> Step on </div>
<div><i class="glyphicon glyphicon-flag"></i> report </div>
</div>
<!-- Input box -->
<form class="form-horizontal comment-publish hidden">
<input type="text" class="form-control" placeholder=" Write down your comments ...">
<button type="button" class="btn btn-default btn-grey"> Release </button>
</form>
<!-- // Input box -->
</div>
<div class="comment-item">
<div class="header">
<div class="user-info">
<img class="avater" src="/assets/home/qa/user_head.jpg" alt="">
<strong class="uname"> The user nickname </strong>
</div>
<div class="time">2 Hours before </div>
</div>
<div class="body">
You can't say that , It is their vision that makes them unacceptable . What China has done now is to make their world outlook collapse [ Laugh with tears ][ Laugh with tears ]
</div>
<div class="footer">
<div><i class="glyphicon glyphicon-thumbs-up"></i> 5</div>
<div><i class="glyphicon glyphicon-share-alt"></i> reply </div>
<div><i class="glyphicon glyphicon-thumbs-down"></i> Step on </div>
<div><i class="glyphicon glyphicon-flag"></i> report </div>
</div>
<!-- Input box -->
<form class="form-horizontal comment-publish hidden">
<input type="text" class="form-control" placeholder=" Write down your comments ...">
<button type="button" class="btn btn-default btn-grey"> Release </button>
</form>
<!-- // Input box -->
</div>
<div class="comment-item reply">
<div class="header">
<div class="user-info">
<img class="avater" src="/assets/home/qa/user_head.jpg" alt="">
<strong class="uname"> The user nickname </strong>
</div>
<div class="time">2 Hours before </div>
</div>
<div class="body">
You can't say that , It is their vision that makes them unacceptable . What China has done now is to make their world outlook collapse [ Laugh with tears ][ Laugh with tears ]
</div>
<div class="footer">
<div><i class="glyphicon glyphicon-thumbs-up"></i> 5</div>
<div><i class="glyphicon glyphicon-share-alt"></i> reply </div>
<div><i class="glyphicon glyphicon-thumbs-down"></i> Step on </div>
<div><i class="glyphicon glyphicon-flag"></i> report </div>
</div>
<!-- Input box -->
<form class="form-horizontal comment-publish hidden">
<input type="text" class="form-control" placeholder=" Write down your comments ...">
<button type="button" class="btn btn-default btn-grey"> Release </button>
</form>
<!-- // Input box -->
</div>
<div class="comment-item">
<div class="header">
<div class="user-info">
<img class="avater" src="/assets/home/qa/user_head.jpg" alt="">
<strong class="uname"> The user nickname </strong>
</div>
<div class="time">2 Hours before </div>
</div>
<div class="body">
You can't say that , It is their vision that makes them unacceptable . What China has done now is to make their world outlook collapse [ Laugh with tears ][ Laugh with tears ]
</div>
<div class="footer">
<div><i class="glyphicon glyphicon-thumbs-up"></i> 5</div>
<div><i class="glyphicon glyphicon-share-alt"></i> reply </div>
<div><i class="glyphicon glyphicon-thumbs-down"></i> Step on </div>
<div><i class="glyphicon glyphicon-flag"></i> report </div>
</div>
<!-- Input box -->
<form class="form-horizontal comment-publish hidden">
<input type="text" class="form-control" placeholder=" Write down your comments ...">
<button type="button" class="btn btn-default btn-grey"> Release </button>
</form>
<!-- // Input box -->
</div>
<div class="comment-item">
<div class="header">
<div class="user-info">
<img class="avater" src="/assets/home/qa/user_head.jpg" alt="">
<strong class="uname"> The user nickname </strong>
</div>
<div class="time">2 Hours before </div>
</div>
<div class="body">
You can't say that , It is their vision that makes them unacceptable . What China has done now is to make their world outlook collapse [ Laugh with tears ][ Laugh with tears ]
</div>
<div class="footer">
<div><i class="glyphicon glyphicon-thumbs-up"></i> 5</div>
<div><i class="glyphicon glyphicon-share-alt"></i> reply </div>
<div><i class="glyphicon glyphicon-thumbs-down"></i> Step on </div>
<div><i class="glyphicon glyphicon-flag"></i> report </div>
</div>
<!-- Input box -->
<form class="form-horizontal comment-publish hidden">
<input type="text" class="form-control" placeholder=" Write down your comments ...">
<button type="button" class="btn btn-default btn-grey"> Release </button>
</form>
<!-- // Input box -->
</div>
</div>
<!-- // Comment list -->
<!-- Comment -->
<form class="form-horizontal comment-publish">
<input type="text" name="content" class="form-control" placeholder=" Write down your comments ...">
<button type="button" class="btn btn-default btn-grey"> Release </button>
</form>
<!-- // Comment -->
</div>
<!-- // Comment box -->
</div>
{
% else %}
<div class="answer-content box-wrap">
No one answered the question for the time being
</div>
{
% endif %}
<!-- // Answer the content area -->
{
{
self.link_more() }}
</div>
<div class="col-md-3 right-content">
<!-- About author -->
<div class="about-user box-wrap">
<div class="user-info">
<div class="avater">
<img src="/assets/home/qa/user_head.jpg" alt=" The avatars ">
</div>
<div class="desc">
<h4> Shudake </h4>
<p>《 Notes on actual combat of Internet marketers 》 New books are on the market ; official account : Shudake .</p>
</div>
</div>
<!-- User statistics -->
<div class="qa-stats">
<div>
<span> answer </span>
<strong>309</strong>
</div>
<div>
<span> article </span>
<strong>40</strong>
</div>
<div>
<span> Concern </span>
<strong>85,265</strong>
</div>
</div>
<!-- // User statistics -->
<div class="menu-ls">
<div>
<a href="#" class="btn btn-info btn-sm"><i class="glyphicon glyphicon-plus"></i> Pay attention to him </a>
</div>
<div>
<a href="#" class="btn btn-default btn-sm btn-grey"><i class="glyphicon glyphicon-comment"></i> Send private messages </a>
</div>
</div>
</div>
<!-- // About author -->
<!-- Related issues -->
<div class="rel-ques box-wrap">
<div class="title"> Related issues </div>
<div class="rel-que-ls">
<div>
<a href="#"> After the outbreak , Will you retaliate for consumption ?</a><span>30 answer </span>
</div>
<div>
<a href="#"> Where do you want to go after the epidemic ? With whom ?</a><span>19 answer </span>
</div>
<div>
<a href="#"> If we can survive this epidemic , What do you want to do most ?</a><span>21 answer </span>
</div>
<div>
<a href="#"> May I ask whether this epidemic situation may have a positive impact ?</a><span>9 answer </span>
</div>
<div>
<a href="#"> What do you want to do if the epidemic is over ?</a><span>3 answer </span>
</div>
</div>
</div>
<!-- // Related issues -->
<!-- Right footer -->
<div class="right-footer">
<a href="#"> User guide </a><span class="dot">·</span>
<a href="#"> User usage protocol </a><span class="dot">·</span>
<a href="#"> User privacy policy </a>
<br />
<a href="#"> Infringement report </a><span class="dot">·</span>
<a href="#"> Online harmful information reporting area </a>
<br />
<a href="#"> Beijing ICP Prove The first 10001000 Number </a>
<br />
<a href="#"> Beijing ICP To prepare The first 10001000 Number </a>
<br />
<a href="#"> Contact us © 2020 Online Q & A </a>
</div>
<!-- // Right footer -->
</div>
</div>
</div>
</div>
<div class="layout-footer">
<a href="#" data-toggle="tooltip" title=" Feedback "><i class="glyphicon glyphicon-briefcase"></i></a>
<a href="#" data-toggle="tooltip" title=" Back to the top "><i class="glyphicon glyphicon-arrow-up"></i></a>
</div>
<!-- Write the answer , Dialog box -->
<div class="modal fade" id="addComment" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<form class="form-horizontal modal-dialog" role="document"
method="post" action="{
{ url_for('qa.detail', q_id=question.id) }}">
{
{
form.csrf_token }}
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel"> Write the answer </h4>
</div>
<div class="modal-body">
<div class="form-group">
{
{
form.content }}
{
{
ckeditor.load() }}
{
{
ckeditor.config(name='content') }}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"> close </button>
<button type="submit" class="btn btn-primary"> Submit </button>
</div>
</div>
</form>
</div>
<!-- // Write the answer , Dialog box -->
{
% endblock %}
{
% block js_inline %}
// Click on , To view more , Put the detailed one p The label shows , Hide yourself
$('.show-desc').click(function () {
$(this).addClass('hidden');
$(this).next().removeClass('hidden')
})
$('.show-all').click(function () {
$(this).addClass('hidden');
$(this).prev().removeClass('hidden')
})
{
% endblock %}
{
% block js_extra %}
<script>
$(function(){
var form = $('.comment-publish');
$('.btn', form).click(function() {
var _form =$(this).parent()
var content = $('input[name=content]', _form)
$.ajax({
url: '{
{ url_for("qa.comments", answer_id=answer.id) }}',
method: 'post',
data: {
content: content.val()
},
complete: function(res){
console.log('res:', res)
if(res.status === 201) {
window.alert(' Comment successful ');
content.val('')
}else if (res.status === 400) {
window.alert(res.responseJSON.message);
} else {
window.alert(' request was aborted , Please try again later ');
}
}
})
})
})
</script>
{
% endblock %}
Comments and replies list loading _
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
from utils import constants
db = SQLAlchemy()
class User(db.Model):
""" The user model """
__tablename__ = 'accounts_user'
id = db.Column(db.Integer, primary_key=True, autoincrement=True) # Primary key
# user name , For logging in
username = db.Column(db.String(64), unique=True, nullable=False)
# The user nickname
nickname = db.Column(db.String(64))
password = db.Column(db.String(256), nullable=False)
# User's Avatar address
avatar = db.Column(db.String(256))
# Whether it works , Invalid users will not be able to log on to the system
status = db.Column(db.SmallInteger,
default=constants.UserStatus.USER_ACTIVE.value,
comment=' User state ')
# Is it super administrator , Administrators can manage all content
is_super = db.Column(db.SmallInteger,
default=constants.UserRole.COMMON.value)
# Creation time
created_at = db.Column(db.DateTime, default=datetime.now)
# Last modified time
updated_at = db.Column(db.DateTime,
default=datetime.now, onupdate=datetime.now)
# profile = db.relationship('UserProfile')
@property
def is_authenticated(self):
return True
@property
def is_active(self):
""" Only a valid user can log in to the system """
return self.status == constants.UserStatus.USER_ACTIVE.value
@property
def is_anonymous(self):
return False
def get_id(self):
return '{}'.format(self.id)
def __str__(self):
return self.nickname
class UserProfile(db.Model):
""" User details """
__tablename__ = 'accounts_user_profile'
id = db.Column(db.Integer, primary_key=True) # Primary key
# user name , For logging in
username = db.Column(db.String(64), unique=True, nullable=False)
# User's real name
real_name = db.Column(db.String(64))
# The user's motto
maxim = db.Column(db.String(128))
# Gender
sex = db.Column(db.String(16))
# Address
address = db.Column(db.String(256))
# Creation time
created_at = db.Column(db.DateTime, default=datetime.now)
# Last modified time
updated_at = db.Column(db.DateTime,
default=datetime.now, onupdate=datetime.now)
# Associated users
user_id = db.Column(db.Integer, db.ForeignKey('accounts_user.id'))
# Create a one-to-one relationship attribute for users user.profile profile.user
user = db.relationship('User', backref=db.backref('profile', uselist=False))
class UserLoginHistory(db.Model):
__tablename__ = 'accounts_login_history'
id = db.Column(db.Integer, primary_key=True) # Primary key
# user name , For logging in
username = db.Column(db.String(64), nullable=False)
# Account platform
login_type = db.Column(db.String(32))
# IP Address
ip = db.Column(db.String(32))
# user-agent
ua = db.Column(db.String(128))
# Creation time
created_at = db.Column(db.DateTime, default=datetime.now)
# Associated users
user_id = db.Column(db.Integer, db.ForeignKey('accounts_user.id'))
# Set up one to many attributes with users ,user.history_list
user = db.relationship('User', backref=db.backref('history_list', lazy='dynamic'))
class Question(db.Model):
""" problem """
__tablename__ = 'qa_question'
id = db.Column(db.Integer, primary_key=True) # Primary key
# Question title
title = db.Column(db.String(128), nullable=False)
# Problem description
desc = db.Column(db.String(256))
# Question picture
img = db.Column(db.String(256))
# Details of the problem
content = db.Column(db.Text, nullable=False)
# Number of visitors
view_count = db.Column(db.Integer, default=0)
# Logical deletion
is_valid = db.Column(db.Boolean, default=True)
# Sort
reorder = db.Column(db.Integer, default=0)
# Creation time
created_at = db.Column(db.DateTime, default=datetime.now)
# Last modified time
updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
# Associated users
user_id = db.Column(db.Integer, db.ForeignKey('accounts_user.id'))
# Set up one to many attributes with users ,user.question_list
user = db.relationship('User', backref=db.backref('question_list', lazy='dynamic'))
@property
def get_img_url(self):
return 'medias/' + self.img if self.img else ''
@property
def comment_count(self):
""" Number of comments """
return self.question_comment_list.filter_by(is_valid=True).count()
@property
def follow_count(self):
""" Focus on quantity """
return self.question_follow_list.filter_by(is_valid=True).count()
@property
def answer_count(self):
return self.answer_list.filter_by(is_valid=True).count()
@property
def tags(self):
""" The label of the article """
return self.tag_list.filter_by(is_valid=True)
@property
def love_count(self):
""" Number of likes """
return self.question_love_list.count()
class QuestionTags(db.Model):
""" Label under question """
__tablename__ = 'qa_question_tags'
id = db.Column(db.Integer, primary_key=True) # Primary key
# Tag name
tag_name = db.Column(db.String(16), nullable=False)
# Logical deletion
is_valid = db.Column(db.Boolean, default=True)
# Creation time
created_at = db.Column(db.DateTime, default=datetime.now)
# Related questions
q_id = db.Column(db.Integer, db.ForeignKey('qa_question.id'))
# Establish one to many attributes of the problem
question = db.relationship('Question', backref=db.backref('tag_list', lazy='dynamic'))
class Answer(db.Model):
""" The answer to the question """
__tablename__ = 'qa_answer'
id = db.Column(db.Integer, primary_key=True) # Primary key
# Details of the answers
content = db.Column(db.Text, nullable=False)
# Logical deletion
is_valid = db.Column(db.Boolean, default=True)
# Creation time
created_at = db.Column(db.DateTime, default=datetime.now)
# Last modified time
updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
# Associated users
user_id = db.Column(db.Integer, db.ForeignKey('accounts_user.id'))
# Related questions
q_id = db.Column(db.Integer, db.ForeignKey('qa_question.id'))
# Set up one to many attributes with users
user = db.relationship('User', backref=db.backref('answer_list', lazy='dynamic'))
# Establish one to many attributes of the problem
question = db.relationship('Question', backref=db.backref('answer_list', lazy='dynamic'))
@property
def love_count(self):
""" Number of likes """
return self.answer_love_list.count()
class AnswerComment(db.Model):
""" Comments answered """
__tablename__ = 'qa_answer_comment'
id = db.Column(db.Integer, primary_key=True) # Primary key
# Comment content
content = db.Column(db.String(512), nullable=False)
# Number of people in favor
love_count = db.Column(db.Integer, default=0)
# Whether the comments are public
is_public = db.Column(db.Boolean, default=True)
# Logical deletion
is_valid = db.Column(db.Boolean, default=True)
# Creation time
created_at = db.Column(db.DateTime, default=datetime.now)
# Last modified time
updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
# reply ID
reply_id = db.Column(db.Integer, db.ForeignKey('qa_answer_comment.id'), nullable=True)
# Associated users
user_id = db.Column(db.Integer, db.ForeignKey('accounts_user.id'))
# Related answers
answer_id = db.Column(db.Integer, db.ForeignKey('qa_answer.id'))
# Related questions
q_id = db.Column(db.Integer, db.ForeignKey('qa_question.id'))
# Set up one to many attributes with users
user = db.relationship('User', backref=db.backref('answer_comment_list', lazy='dynamic'))
# Build one to many attributes with answers
answer = db.relationship('Answer', backref=db.backref('answer_comment_list', lazy='dynamic'))
# Establish one to many attributes of the problem
question = db.relationship('Question', backref=db.backref('question_comment_list', lazy='dynamic'))
class AnswerLove(db.Model):
""" Answer like """
__tablename__ = 'qa_answer_love'
id = db.Column(db.Integer, primary_key=True) # Primary key
created_at = db.Column(db.DateTime, default=datetime.now)
# Associated users
user_id = db.Column(db.Integer, db.ForeignKey('accounts_user.id'))
# Related answers
answer_id = db.Column(db.Integer, db.ForeignKey('qa_answer.id'))
# Related questions
q_id = db.Column(db.Integer, db.ForeignKey('qa_question.id'))
# Set up one to many attributes with users
user = db.relationship('User', backref=db.backref('answer_love_list', lazy='dynamic'))
# Build one to many attributes with answers
answer = db.relationship('Answer', backref=db.backref('answer_love_list', lazy='dynamic'))
# Establish one to many attributes of the problem
question = db.relationship('Question', backref=db.backref('question_love_list', lazy='dynamic'))
class AnswerCollect(db.Model):
""" Favorite answers """
__tablename__ = 'qa_answer_collect'
id = db.Column(db.Integer, primary_key=True) # Primary key
# Creation time
created_at = db.Column(db.DateTime, default=datetime.now)
# Logical deletion
is_valid = db.Column(db.Boolean, default=True)
# Associated users
user_id = db.Column(db.Integer, db.ForeignKey('accounts_user.id'))
# Related questions
q_id = db.Column(db.Integer, db.ForeignKey('qa_question.id'))
# Related answers
answer_id = db.Column(db.Integer, db.ForeignKey('qa_answer.id'))
# Set up one to many attributes with users
user = db.relationship('User', backref=db.backref('answer_collect_list', lazy='dynamic'))
# Establish one to many attributes of the problem
question = db.relationship('Question', backref=db.backref('question_collect_list', lazy='dynamic'))
# Build one to many attributes with answers
answer = db.relationship('Answer', backref=db.backref('answer_collect_list', lazy='dynamic'))
class QuestionFollow(db.Model):
""" Concerns """
__tablename__ = 'qa_question_follow'
id = db.Column(db.Integer, primary_key=True) # Primary key
created_at = db.Column(db.DateTime)
is_valid = db.Column(db.Boolean, default=True, comment=' Logical deletion ')
# Associated users
user_id = db.Column(db.Integer, db.ForeignKey('accounts_user.id'))
# Related questions
q_id = db.Column(db.Integer, db.ForeignKey('qa_question.id'))
# Set up one to many attributes with users
user = db.relationship('User', backref=db.backref('question_follow_list', lazy='dynamic'))
# Establish one to many attributes of the problem
question = db.relationship('Question', backref=db.backref('question_follow_list', lazy='dynamic'))
def number_split(num):
"""
Number formatting
12345678 => 12,345,678
:param num: Numbers that need to be formatted
:return: Formatted string
"""
return '{:,}'.format(int(num))
边栏推荐
- Traversal of binary tree -- restoring binary tree by two different Traversals
- Deep search + backtracking
- Convert result set of SQL to set
- Get the third-party interface
- JVM tuning 6: GC log analysis and constant pool explanation
- 初步了解多任务学习
- Paper reproduction: pare
- 【深入kotlin】 - Flow 进阶
- Section III: structural characteristics of cement concrete pavement
- 深度学习分布式训练
猜你喜欢

Titanic rescued - re exploration of data mining (ideas + source code + results)

Number of atoms (easy to understand)

PCB走線到底能承載多大電流

Paper recommendation: relicv2, can the new self supervised learning surpass supervised learning on RESNET?

初步了解多任务学习

Analyze while doing experiments -ndk article -jni uses registernatives for explicit method registration

Introduction to coordinate system in navigation system

Zed2 camera calibration -- binocular, IMU, joint calibration

Huawei equipment configuration MCE

QT Road (2) -- HelloWorld
随机推荐
Get the third-party interface
如何让灯具智能化,单火、零火智能开关怎么选!
Big meal count (time complexity) -- leetcode daily question
KD-Tree and LSH
PCB走线到底能承载多大电流
Minimize maximum
Feynman learning method
深度学习分布式训练
MySQL string to array, merge result set, and convert to array
Topological sorting
Take stock of the AI black technologies in the Beijing Winter Olympic Games, and Shenzhen Yancheng Technology
Opencv learning path (2-1) -- Deep parsing imread function
Vins fusion GPS fusion part
[go deep into kotlin] - get to know flow for the first time
Linked list de duplication
一大厂95后程序员对部门领导不满,删库跑路被判刑
Yolov5 training personal data set summary
Apply the intelligent OCR identification technology of Shenzhen Yanchang technology to break through the bottleneck of medical bill identification at one stroke. Efficient claim settlement is not a dr
The solution "no hardware is configured for this address and cannot be modified" appears during botu simulation
In the future, how long will robots or AI have human creativity?