美文网首页
flask高级编程_鱼书项目_填坑记

flask高级编程_鱼书项目_填坑记

作者: Wei_Lai | 来源:发表于2018-12-06 11:11 被阅读0次

    详细过程可以去我的个人博客上查看,另有flask构建可扩展restful-api过程.
    个人博客,gitbook 下

    本文主要是记录我在鱼书项目遇到的问题

    很多bug都是因为一点小小的原因导致的,所以以后还得仔细。

    1. 数据库表不能添加数据

    产生场景

    localhost:2333/register 注册用户信息,提交后出现如下提示:

    错误提示

    产生原因


    自己粗心,之前已经有添加_password,后来又在末尾加了_password,导致数据表生成不了password,所以在/register 注册后,出现bug。

    解决过程

    在数据库user表中查询不到password字段,于是到model/user.py中查看到自己多写了一遍_password 代码,删除后成功。

    2. 搜索isbn成功,搜索关键字时失败

    搜索关键字
    搜索isbn

    产生原因

    /book/search/
    restful 格式 为 search?q= xxx,重构代码后。route修改有问题。

    解决过程

    /book/search
    修改后正常,还是得细心。
    注意事项
    chrome 浏览器有缓存,修改后,即使网址 为 .../book/search?q=xxx,也会跳转成.../book/searc/q=xxx导致出错,清空一下浏览数据就可以了。

    3. 路由问题

    产生场景

    注册后,重定向产生Bug


    错误提示

    产生原因

    flask_login 中的重定向格式为web.login,这一段可能是我输入有误吧。直接给出了解决方案。

    解决过程

    将web/login 更改为web.login

    4. 有关于前端的问题

    因为最初 的时候,有一段前端代码得注释,当时不熟悉这一块,我还是按照python 中的方法,在前面加#号处理的,结果有问题,后来才发现不应该这样做。很久以前的问题了,当时也没保存,所以没有具体图片。当时的解决方案是把那些要注释掉的前端代码全部删除掉了。

    5. flask调试

    调试端口号默认为5000。
    localhost:5000,之前没仔细查看,一直在生产模式下调试,还一直进不了断点0.0

    6. 新增个人中心

    代码如下

    @web.route('/personal')
    def personal_center():
        cur_user = User.query.get_or_404(current_user.id)  
    # 从数据库中查询出当前用户数据
        user = cur_user.summary  
     # summary返回一个自定义的字典,详情在user模型下
        # b = a.summary
        return render_template('personal.html', user=user)  # 网页模板下
    
    
    summray
    前端代码

    因为 user 是一个字典形式,从而得到数据。

    7. 新增修改密码

    之前没有看前端代码,所以password字段有问题,更改后,成功

    @web.route('/change/password', methods=['GET', 'POST'])
    @login_required 
    def change_password():
        form = ChangePasswordForm(request.form)
    
        if request.method == 'POST' and form.validate():
            if current_user.check_password(form.old_password.data):
                current_user.change_password(form.password1.data)
                flash('您的密码已重置,请使用新密码登录')
                return redirect(url_for('web.login'))
            flash('密码更改失败')
        return render_template('auth/change_password.html')
    
    前端代码

    把 前端代码中的原密码改成old_password,新密码,确认新密码改为password1,password2 就可以了。
    暴露的问题,对前端这一块不熟。

    8 . 新增API搜索的图书保存的mysql中

    最初使用的如下方式,一点都不优雅,后更改

        @classmethod
        def insert_into_sql(cls, books):
            for b in books:    # 优化后如上
                with db.auto_commit():
                    try:
                        if Book.query.filter_by(isbn=b.isbn).first():
                            continue
                        book = Book()
                        book.title = b.title
                        book.author = b.author
                        book.binding =b.binding
                        book.publisher = b.publisher
                        book.price = b.price
                        book.pages = b.pages
                        book.isbn = b.isbn
                        book.summary = b.summary
                        book.image = b.image
                        db.session.add(book)
                    except sqlalchemy.exc.DataError:
                        pass
    

    如下:

        @classmethod
        def insert_into_sql(cls, books):
            # book model 写入
            import sqlalchemy
            for b in books: # books是一个列表,每个元素是一个Book实例化后的对象
                # print(111111111111, b.pages)
                if Book.query.filter_by(isbn=b.isbn).first():  # 因为重复的isbn不能添加
                            continue
                with db.auto_commit():
                    book = Book()
                    book.set_attrs(b.__dict__)  # [b1, b2, b3] 
                    # 类实例化后的一个对象 b.author b.title
                    db.session.add(book)
    

    base模型的部分代码:

    class Base(db.Model):
        __abstract__ = True
        create_time = Column('create_time',Integer)
        status = Column(SmallInteger, default=1)
    
        def __init__(self):
            self.create_time = int(datetime.now().timestamp())
    
        def set_attrs(self, attrs_dict):
            for key, value in attrs_dict.items():
                if hasattr(self, key) and key != 'id':
                    setattr(self, key, value)
    

    详细解释

    这一块,考虑的点特别多。因为从API拿来的数据,并不是很可靠。所以有一些数据为None,或者超出了长度,用以前的代码可能会报错

        def __init__(self, data):
            self.title = data['title']
            self.author = '、'.join(data['author'])
            self.binding = data['binding']
            self.publisher = data['publisher']
            self.image = data['image']
            # self.price = '¥' + data['price']  
    # 因为价格可能为NONE,str不能和NONE相加,会报错。
    # '¥'去掉,因为api中部分带货币单位
            self.price = data['price'] 
    
            self.isbn = data['isbn']
            self.pubdate = data['pubdate']
    
    # summuy长度最多取1000.
            self.summary = data['summary'][:1000] if data['summary'] else ''
            self.pages = data['pages'].replace('页', '') if data['pages'] else None
    
        @property
        def intro(self):
            intros = filter(lambda x: True if x else False,
                            [self.author, self.publisher, self.price])
            return ' / '.join(intros)
    
    

    以上是在view_modles 下book.py做的处理。要细心,多进行代码优化。

    web/book.py部分代码

    @web.route("/book/search")
    def search():
        """
        搜索书籍路由
        """
        # 实例化我们自定义的SearchForm,需要传入一个字典作为要校验的参数
        form = SearchForm(request.args)
        # validate()方法返回True/False来标示是否校验通过
        books = BookCollection()
        # if not form.validate():
        #     # errors为错误信息提示(上面定义的message)
        #     flash("搜索的关键字不符合要求,请重新输入关键字")
        #     return render_template('search_result.html', books=books)
        # 从form中获取校验后的参数,不从request里拿,
    #因为我们可能会对数据进行预处理或者默认值的给定
        q = form.q.data.strip()
        page = form.page.data
        isbn_or_key = is_isbn_or_key(q)
        yushu_book = YuShuBook()
        if form.validate():
            if isbn_or_key == 'isbn':
                yushu_book.search_by_isbn(q)
                books.fill(yushu_book,q)
                # print(11111, books.books)
                # for b in books.books:
                #     print('title', b.title)
                #     print('author', b.author)
            # result = YuShuBook.search_by_isbn(q)
            # result = BookViewModel.package_single(result,q) 
            else:
                yushu_book.search_by_key(q,page)        
            # result = YuShuBook.search_by_keyword(q,page)
            # result = BookViewModel.package_collection(result,q)
        # return jsonify(result)
                books.fill(yushu_book,q)
            Book.insert_into_sql(books.books)   # 搜索的信息保存到SQL中
        else:
            flash("搜索的关键字不符合要求,请重新输入关键字")
    
        # return jsonify(books)  
    # TypeError: Object of type BookCollection is not JSON serializable
        # return json.dumps(books, default=lambda o: o.__dict__)
        return render_template('search_result.html', books=books)
    

    相关文章

      网友评论

          本文标题:flask高级编程_鱼书项目_填坑记

          本文链接:https://www.haomeiwen.com/subject/bayncqtx.html