python-flask(四)

表与表之间的关系

SQLAlchemy使用

常用的过滤器:
        filter()    把过滤器添加到原查询上,返回一个新查询
        filter_by() 把等值过滤器添加到原查询上,返回一个新查询
        limit()     使用指定的值限定原查询返回的结果
        offset()    偏移原查询返回的结果,返回一个新查询
        order_by()  根据指定条件对原查询结果进行排序,返回一个新查询
        group_by()  根据指定条件对原查询结果进行分组,返回一个新查询


        执行器的使用
        all()           以列表形式返回查询的所有结果
        first()         返回查询的第一个结果,如果未查到,返回None
        first_or_404()  返回查询的第一个结果,如果未查到,返回404
        get()           返回指定主键对应的行,如不存在,返回None
        get_or_404()    返回指定主键对应的行,如不存在,返回404
        count()         返回查询结果的数量
        paginate()      返回一个Paginate对象,它包含指定范围内的结果


常用的字段
    类型名                   python类型              说明
    Integer                     int                  普通整数,一般是32位
    SmallInteger                int                  取值范围小的整数,一般是16位
    BigInteger                  int或long            不限制精度的整数
    Float                       float                浮点数
    Numeric                     decimal.Decimal      普通整数,一般是32位
    String                      str                  变长字符串
    Text                        str                  变长字符串,对较长或不限长度的字符串做了优化
    Unicode                     unicode              变长Unicode字符串
    UnicodeText                 unicode              变长Unicode字符串,对较长或不限长度的字符串做了优化
    Boolean                     bool                 布尔值
    Date                        datetime.date        时间
    Time                        datetime.datetime    日期和时间
    LargeBinary                 str                  二进制文件
    Enum                        enum                 枚举类型
常用列选项
    primary_key         如果为True,代表表的主键
    unique              如果为True,代表这列不允许出现重复的值
    index               如果为True,为这列创建索引,提高查询效率
    nullable            如果为True,允许有空值,如果为False,不允许有空值
    default             为这列定义默认值,如default=1
常用的关系选项
    backref             在关系的另一模型中添加反向引用,用于找到父表
    primary join        明确指定两个模型之间使用的联结条件
    uselist             如果为False,不使用列表,而使用标量值
    order_by            指定关系中记录的排序方式
    secondary           指定多对多中记录的排序方式
    secondary join      在SQLAlchemy中无法自行决定时,指定多对多关系中的二级联结条件

文章表

python-flask(四)_第1张图片
迁移出现问题时:

  1. 删除migrations文件中的version文件
  2. 删除数据库中的版本delete表
  3. migrate和update
关系:
1对多:
1: user
多: article

建立数据库之间的引用关系:
class User(db.Model):
    __tablename__ ='user1'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)  主键

class Article(db.Model):
    ....
    # 建立两张表之间的关系
    user_id = db.Column(db.Integer, db.ForeignKey('表名.主键'), nullable=False)   是article的外键

代码的引用关系:
relationship  关系

在1:user上添加:
class User(db.Model):
    __tablename__ ='user1'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)  主键
    # 代码
    articles = db.relationship('Article', backref='user')

 正向: user对象.articles  --- > [<article>,<article>,...]

 反向: article对象.user ----> user对象      {
     {
     article.user.username}}

迁移出现问题时:

  1. 删除migrations文件中的version文件
  2. 删除数据库中的版本delete表
  3. migrate和update
manage.py
from apps.models.blog_model import User,Article

apps:__init__.py
app.register_blueprint(article_bp)

blog_model.py
class Article(db.Model):
    __tablename__ = 'article'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(100), nullable=False)
    content = db.Column(db.String(255), nullable=False)
    pdatetime = db.Column(db.DateTime, default=datetime.now)
    love_num = db.Column(db.Integer, default=0)
    click_num = db.Column(db.Integer, default=0)
    # 建立两张表之间的关系
    user_id = db.Column(db.Integer, db.ForeignKey('user1.id'), nullable=False)
    comments = db.relationship('Comment', backref='article')

    def __str__(self):
        return self.title

user_view.py
# 首页
@blog_bp.route('/', endpoint='index')
def index():
    articles = Article.query.all()
    # uname = request.cookies.get('uname')
    # print(uname)
    uname = session.get('uname')
    print(uname)
    return render_template('index.html', articles=articles)
article_view.py
from flask import Blueprint, request, render_template, redirect, url_for
from apps.models.blog_model import Article, User, Comment
from exts import db

article_bp = Blueprint('article', __name__, url_prefix='/article')

# 发表文章
@article_bp.route('/add', endpoint='add', methods=['GET', 'POST'])
def article_add():
    if request.method == 'POST':
        title = request.form.get('title')
        content = request.form.get('content')
        user_id = request.form.get('author')
        # 添加文章
        article = Article()
        article.title = title
        article.content = content
        #
        article.user_id = user_id

        db.session.add(article)
        db.session.commit()
        return redirect(url_for('blog.index'))
    else:
        users = User.query.all()
        return render_template('article_add.html', users=users)

index.html

{
     % extends 'base.html' %}
{
     % block mycss %}


{
     % endblock %}

{
     % block content %}
    
{ % for article in articles %}

{ { url_for('article.detail')}}?aid={ { article.id}}">{ { article.title}}

{ { article.content }}

{ { article.user.username}}  ; ; ; ; ; ; { { article.click_num}}  ; ; ; ; ; ; { { article.love_num}}
{ % endfor %}
{ % endblock %}

详情

 <h3><a href="{
     {url_for('article.detail')}}?aid={
     {article.id}}">{
     {
     article.title}}</a></h3>

# 文章详情
@article_bp.route('/detail', endpoint='detail')
def article_detail():
    aid = request.args.get('aid')
    # 找文章对象
    article = Article.query.get(aid)
    article.click_num += 1
    db.session.commit()
    users = User.query.all()
    return render_template('article_detail.html', article=article, users=users)

创建detail.html
点赞操作:使用ajax,实现局部页面的异步操作。

article_view.py
# 点赞
@article_bp.route('/love', endpoint='love')
def article_love():
    aid = request.args.get('aid')
    article = Article.query.get(aid)
    article.love_num += 1
    db.session.commit()

    return {
     'msg': 'ok', 'number': article.love_num}

article_detail.html
{
     % block myjs%}
<script>
    $('#love').click(function(){
     
        var $this = $(this);
        aid = $(this).attr('tag');
        url = '{
     {url_for('article.love')}}';
        $.getJSON(url,{
     aid:aid},function(data){
     
           console.log(data);
           $this.next().text(data.number)
        });
    })
</script>
{
     % endblock %}

发表文章

article_view.py
# 发表文章
@article_bp.route('/add', endpoint='add', methods=['GET', 'POST'])
def article_add():
    if request.method == 'POST':
        title = request.form.get('title')
        content = request.form.get('content')
        user_id = request.form.get('author')
        # 添加文章
        article = Article()
        article.title = title
        article.content = content
        #
        article.user_id = user_id

        db.session.add(article)
        db.session.commit()
        return redirect(url_for('blog.index'))
    else:
        users = User.query.all()
        return render_template('article_add.html', users=users)
        
article_add.html

评论表
python-flask(四)_第2张图片
多对多:
步骤:

  1. user comment模型
  2. 建立模型之间的关系:多对多之间的关系表
    方式1:
    class comment_user(db.Model):
    tablename=‘xxx’
    user_id
    comment_id
  3. 建立relationship关系
    class User(db.Model):
    comments = db.relationship(‘Comment’, backref=‘users’,secondary=‘comment_user’) 就是关系表名
```python
# 文章评论
@article_bp.route('/comment', endpoint='comment', methods=['POST'])
def article_comment():
    '''
       收: article_id content  user_id
            创建Comment对象  保存数据
            操作关系表(comment_user): user_id   comment_id
       送:  跳转到详情页

    '''
    content = request.form.get('content')
    user_id = request.form.get('author')
    article_id = request.form.get('aid')
    # print(content,user_id,article_id)

    user = User.query.get(user_id)

    comment = Comment()
    comment.content = content
    comment.article_id = article_id

    user.comments.append(comment)  # user.comments.append(comment)
    db.session.commit()

    comment1 = Comment()
    comment1.content='aaaaaa'
    comment1.article_id = article_id

    user1 = User.query.get(3)
    comment1.users.append(user1)

    db.session.add(comment)
    db.session.commit()

    url = url_for('article.detail') + '?aid=' + str(article_id)
    return redirect(url)

会话机制:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200709153359557.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NodW5qaWFueGFpb3NoaQ==,size_16,color_FFFFFF,t_70)

会话机制:
http 协议  ---》 无状态协议
    设置cookie:
     通过response对象:
     response = make_response()
     response.set_cookie(key,value,max_age=(单位second),expires=(要求是detetime类型))

     expires = datetime(year=2018,month=11,day=5)
    #expires是这么设置的
    expires = datetime.now() + timedelta(days=13,hours=16)#这里一定要减8个小时
    #在新版本的http协议中,expires参数视为被废弃的
    #max_age,在IE8一下的浏览器是不支持的
    # res.set_cookie('username','zhiliao',expires=expires)#cookies只有在响应返回的时候才能设置,
    # max_age最大的cookies报存时间,expires到期时间

    删除cookie:
     通过response对象:
     response = make_response() | redirect()
     response.delete_cookie(key)

    获取cookie:
     后端:  request.cookies.get(key)  ----> cookie值
     前端:   {
    { request.coookies['key']  }}


session :
  session是系统的全局对象
  from flask import session
  设置:
     session[key]=value

     开辟空间  ---》 session唯一标识   ----》 设置到cookie 中

      必须在settings.py 中添加:
      secret_key ='djfkljsdklf3747'

  获取:
     session.get('key') ---->value

  删除: session.clear()   ----> 空间+cookie都会删除

你可能感兴趣的:(flask,python,cookie,flask)