What is correct way to handle form submission in beego?

huangapple go评论77阅读模式
英文:

What is correct way to handle form submission in beego?

问题

我正在尝试在beego中提交表单数据并将其存储到数据库中,并有一些问题:

  • 如何正确处理请求并将其转换为对象?
  • 我应该验证请求还是转换后的对象?

我的控制器动作:

func (c *ServicesController) Edit() {
    var err error
    var id, _ = c.GetUint64(":id")
    var serviceModel = models.Service{}
    var service models.Service

    service, err = serviceModel.FindById(id)

    c.Data["Service"] = service

    if err == orm.ErrNoRows || err == orm.ErrMissPK  {
        c.Abort("404")
    }

    if c.Ctx.Input.IsPost() {
        err = nil
        if err := c.ParseForm(&service); err != nil {
            c.Abort("500")
        }

        serviceModel.CreateOrUpdate(service)
    }

    c.TplName = "services/edit.html"
}

模型:

type Service struct {
    Id       uint64 `form:"-"`
    Name     string `orm:"size(100)" valid:"Required; MaxSize(100)" form:"name"`
}

func init() {
    orm.RegisterModel(new(Service))
}

func (s *Service) FindById(id uint64) (Service, error) {
    o := orm.NewOrm()
    service := Service{Id: id}
    err := o.Read(&service)

    return service, err
}

func (s *Service) CreateOrUpdate(service Service)  {
    o := orm.NewOrm()
    o.InsertOrUpdate(&service)
}

但是,当我尝试提交表单(使用InsertOrUpdate)时,它仍然会创建新对象,因为表单中没有id字段(因为我从路由的id参数中检索对象)。我应该无论如何将id传递给表单,还是有什么其他方法可以解决这个问题?

英文:

I'm trying to submit form data in beego and store it to database. And have some questions:

  • how correct handle request and transform it to object?
  • Should I validate request or transformed object?

My controller action:

func (c *ServicesController) Edit() {
	var err error
	var id, _ = c.GetUint64(":id")
	var serviceModel = models.Service{}
	var service models.Service

	service, err = serviceModel.FindById(id)

	c.Data["Service"] = service

	if err == orm.ErrNoRows || err == orm.ErrMissPK  {
		c.Abort("404")
	}

	if c.Ctx.Input.IsPost() {
		err = nil
		if err := c.ParseForm(&service); err != nil {
			c.Abort("500")
		}

		serviceModel.CreateOrUpdate(service)
	}

	c.TplName = "services/edit.html"
}

Model:

type Service struct {
	Id       uint64 `form:"-"`
	Name     string `orm:"size(100)" valid:"Required; MaxSize(100)" form:"name"`
}

func init() {
	orm.RegisterModel(new(Service))
}

func (s *Service) FindById(id uint64) (Service, error) {
	o := orm.NewOrm()
	service := Service{Id: id}
	err := o.Read(&service)

	return service, err
}

func (s *Service) CreateOrUpdate(service Service)  {
	o := orm.NewOrm()
	o.InsertOrUpdate(&service)
}

But when I'm trying to submit form (with InsertOrUpdate) it anyway creates new object because I have no id field in the form (because I retrieving object from id param from route). Should I pass id to form anyway or how to hack it?

答案1

得分: 3

在解析表单之后,只需在ID后面添加:

if err := c.ParseForm(&service); err != nil {
    c.Abort("500")
}
service.Id = id

通过查看beego的源代码,我认为你可以这样做:

if c.Ctx.Input.IsPost() {
    c.Input().Add("id", id)
    err = nil
    if err := c.ParseForm(&service); err != nil {
        c.Abort("500")
    }

    serviceModel.CreateOrUpdate(service)
}

但如果不行的话,我建议稍微重构一下你的代码:

func (c *ServicesController) Edit() {
    var id, _ = c.GetUint64(":id")
    var service models.Service{}
    var serviceModel = models.Service{}
    var err error
    
    if c.Ctx.Input.IsPost() {
        if err = c.ParseForm(&service); err != nil {
            c.Abort("500")
        }
        service.Id = id
        serviceModel.CreateOrUpdate(service)
    } else {
        service, err = serviceModel.FindById(id)
        if err == orm.ErrNoRows || err == orm.ErrMissPK  {
            c.Abort("404")
        }
    }

    c.Data["Service"] = service
    c.TplName = "services/edit.html"
}

以上是翻译好的内容,请确认是否满意。

英文:

Just add the ID after you parse the form:

if err := c.ParseForm(&service); err != nil {
    c.Abort("500")
}
service.Id = id

Looking through beego's source, I think you could do:

if c.Ctx.Input.IsPost() {
    c.Input().Add("id", id)
    err = nil
    if err := c.ParseForm(&service); err != nil {
        c.Abort("500")
    }

    serviceModel.CreateOrUpdate(service)
}

But if not, I would just restructure your code a little bit:

func (c *ServicesController) Edit() {
    var id, _ = c.GetUint64(":id")
    var service models.Service{}
    var serviceModel = models.Service{}
    var err error
    
    if c.Ctx.Input.IsPost() {
        if err = c.ParseForm(&service); err != nil {
            c.Abort("500")
        }
        service.Id = id
        serviceModel.CreateOrUpdate(service)
    } else {
    	service, err = serviceModel.FindById(id)
    	if err == orm.ErrNoRows || err == orm.ErrMissPK  {
        c.Abort("404")
    }

    c.Data["Service"] = service
    c.TplName = "services/edit.html"
}

huangapple
  • 本文由 发表于 2017年4月20日 00:15:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/43501021.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定