beego:从入门到放弃

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/github_37320188/article/details/79107380

使用beego创建新项目

beego 的项目基本都是通过 bee 命令来创建的,所以在创建项目之前确保你已经安装了 bee 工具和 beego。如果你还没有安装,那么请查阅 beego 的安装 和 bee 工具的安装


现在一切就绪我们就可以开始创建项目了,打开终端,进入 $GOPATH/src 所在的目录:


创建一个项目名为20180118_loongc_beego的基于beego 的新项目,执行如下命令:

bee new 20180118_loongc_beego


依次执行如下命令:进入目录,运行该项目,在localhost:8080里查看,如下图

cd 20180118_loongc_beego

bee run




配置postgresql 数据库连接

安装beego orm, 降低复杂的ORM(Object-Relational Mapping,对象关系映射)学习曲线,执行如下命令:

go get github.com/astaxie/beego


安装postgresql数据库驱动,执行如下命令:

go get github.com/lib/pq


在main.go文件里添加如下代码:

func init(){

orm.RegisterDriver(“postgres”. orm.DRPostgres)

orm.RegisterDataBase(“default”, “postgres”, “user=postgres password=nasadmin dbname=20180111_loongc_test host=127.0.0.1 port=5432 sslmode=disable”)

orm.RegisterModel(

new(models.User))

orm.RunSyncdb("default", false, true)

}

orm.RegisterDriver为配置postgresql数据库驱动

orm.RegisterDataBase中:

“default”是默认项

“postgres”表示使用的是postgresql数据库

user=postgres password=nasadmin dbname=20180111_loongc_test:分别表示数据库用户名、用户密码、数据库名

host=127.0.0.1 port=5432:分别表示数据库主机地址、数据库端口(5432是postgresql的默认端口)

orm.RegisterModel:表示注册model,每添加一个model文件,都需要register,否则无法访问。当前表示有两个model,User和Topic

模型构造

在文件夹models下新建文件User.go,文件内容如下:

package models


import (

“github.com/astaxie/beego/orm”

)


type User struct {

Id int `json: “id”`

Username string `json:”username”`

Password string `json:”password”`

Role string `json:”role”`

}

模型User构造完成,一个完整的模型还需要添加函数通用方法,这里实现一个用户登录,在文件中添加用户登录验证函数,如下:

func Login(username string, password string)(bool, User){

o := orm.NewOrm()

var user User

err := o.QueryTable(user).Filter(“Username”, username).Filter(“Password”, password).One(&user)

return err != orm.ErrNoRows, user

}


登录界面

在views目录底下添加login.tpl文件,tpl文件是模板写法,本质还是遵循html文件写法,但是支持框架本身的很多变量。文件内容如下:

<!DOCTYPE html>

<html>

<head>

<title>Login page</title>

</head>

<body >

<form id="loginform">

id:<input type="text" name="username" value="{{.Username}}"><br>

pw:<input type="password" name="password" value="{{.Password}}"><br>

<input type="button" value="submit" id="loginbtn">

</form>

<script type="text/javascript" src="/static/js/jquery-3.2.1.js"></script>

<script type="text/javascript">

$(function(){

$('#loginbtn').bind('click', function(){

$.ajax({

url: "/login",

type: "post",

asyns: true,

data: $('#loginform').serialize(),

// dataType: "json",

success: function(res){

console.log(res);

if(res){

window.location.href = "/index";

}else{

window.location.href = "/";

}

// console.log({{.flash.success}});

// {{if .flash.success}}

// window.location.href = {{.flash.success}};

// {{end}}

},

error: function(XMLHttpRequest, testStatus, errorThrown){

console.log(XMLHttpRequest.status);

console.log(XMLHttpRequest.readyState);

console.log(testStatus);

}

});

})

});

</script>

</body>

</html>

控制器

beego框架中,所有视图view显示,都是要定义在控制器里的。当登录页面已经构建好,但是无法在浏览器里马上渲染。这也是beego的局限性,当我需要创建一个新的tpl文件放到服务器端,然后在iframe里通过src引用的时候,新的tpl的名字是动态的,无法动态的在控制器里添加定义。

在当前登录功能中,包括两个控制器,代码如下:

一个登录页面渲染控制器Loginpage,它定义了模板文件的位置,并且定义了两个输入框的值,在登录页面通过{{.Username}}的方法给用户id输入框设置默认值。

一个登录验证控制器Login,它是将用户提交的username和password拿到之后,然后调用之前model里定义的方法,实现验证。验证成功之后进入index.tpl页面(主页),验证失败仍停留在login.tpl。这里仍存在一个beego的问题,如果使用jquery 的ajax方法,beego无法设置返回值,这里原来的Redirect的也会失效,甚至c.TplName方法也同样不起作用。

package controllers


import (

"github.com/astaxie/beego"

"server/20180118_loongc_beego/models"

)


type LoginController struct {

beego.Controller

}


func (c *LoginController) Loginpage() {

c.Data["Username"] = "loongc"

c.Data["Password"] = "123"

c.Data["Error"] = ""

c.TplName = "login.tpl"

}


func (c *LoginController) Login() {

flash := beego.NewFlash()

username, password := c.Input().Get("username"), c.Input().Get("password")

if flag, _ := models.Login(username, password); flag {

// c.SetSecureCookie(beego.AppConfig.String("cookie.secure"), beego.AppConfig.String("cookie.role"), user.Role, 1*1*20*60, beego.AppConfig.String("cookie.domain"), "/", false, true)

c.Redirect("/index", 302)

// c.TplName = "index.tpl"

return

} else {

flash.Error("username or password error")

c.Redirect("/error", 302)

return

}

}

路由

登录界面使用jquery ajax发送的请求是如何被beego框架捕获的,因为很明显的是在这个案例中url给的value是 /login ,这是一个不符合一般化的ajax格式的值,这个是由beego框架自己定义的路由来控制的。在routers目录底下有一个router.go文件,在这里定义了前端的所有请求的最后会被分发到不同控制器,代码如下所示:

package routers


import (

"github.com/astaxie/beego"

"server/20180118_loongc_beego/controllers"

)


func init() {

beego.Router("/", &controllers.LoginController{}, "GET:Loginpage")

beego.Router("/login", &controllers.LoginController{}, "POST:Login")


beego.Router("/index", &controllers.IndexController{}, "GET:Indexpage")

beego.Router("/error", &controllers.IndexController{}, "GET:Error")

}

这里一共定义了四个四个不同的路由,按顺序,分别是初始化web的默认打开页面、登录验证控制器、初始化index.tpl(这个是登录成功之后打开的页面),最后一个是在本实例中设计的登录页面跳转问题,后续章节继续说明。

beego的局限性和解决登录跳转问题
  • 前面已经提到的,对于所有view文件的渲染,都需要事先在控制器里定义好,对于新生成的view文件,目前来看好像无能为力
  • 其次,在于与jquery ajax的配合,beego在这种情况下好像无法返回值,当我在控制器里添加return 一个bool值,并没有拿到,但是通过控制器里存在Redirect方法,console.log(res)时,可以返回Redirect的页面代码。基于以上,ajax无法获得控制页面跳转的参数,不仅如此,beego自身的页面跳转也会出现失效问题。尽管官方提供了扩展方法,但是好像不是很成熟


解决登录跳转

在这里还是坚持ajax做数据发送,因为并不是所有的情况的都是通过input、testxarea、select输入要保存的数据。

在这里提供鉴于console.log(res)出的是要打开页面的代码,那么假设验证登录失败,如果打开的页面是个空的文档,那么if(res) 只有在验证正确的时候才会恒为true,否则就为false,所以我在路由中定义了一个 /error 的路由,在控制器里让它打开一个名为error.tpl的空文档,当验证错误的时候console.log(res)是空的,所以if(res)为false,以此来控制登录验证成功与否时的跳转。但是提示错误信息并没有很好展现

结论

beego是比较完善的框架,但是适用范围仅限于,按照模板输出不同数据。

后台控制跳转,算不得友好,尤其是前端<a>标签都无法单独控制页面跳转。

无法实现灵活的数据数据输入,路由限制决定了数据发送方式被限定太死,不符合实际。尤其是与ajax这种很成熟的数据路由配合都很差。

输入数据的合法性校验,由后端完成,这种工作应该尽量由前端完成。









阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页