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

2018-12-06  本文已影响0人  Wei_Lai

详细过程可以去我的个人博客上查看,另有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)
上一篇下一篇

猜你喜欢

热点阅读