使用Tastypie覆盖模型字段

时间:2013-07-12 15:36:04

标签: python django tastypie

在我的一个视图中,我定义了一个mixin,用于根据用户的会话详细信息动态设置多个模型的techoperator字段,包括客户端模型,以便用户不需要手动填写它们。这个mixin如下:

class GetTechMixin(object):
    """
    View mixin that when the form is saved, sets the
    site_user and operator.
    """
    def form_valid(self, form):
        # Get user
        user = self.request.user

        # Get tech for this user
        site_user = SiteUser.objects.get(user=user)

        # Override the tech and operator fields
        form.instance.tech = site_user
        form.instance.operator = site_user.operator

        # Save the object
        self.object = form.save()

        # Return success URL
        return HttpResponseRedirect(self.get_success_url())

我还设置了以下Tastypie API资源,目的是做同样的事情:

class ClientResource(AbstractModelResource):
    class Meta(AbstractModelResource.Meta):
        queryset = Client.objects.all()
        resource_name = 'client'

    def obj_create(self, bundle, **kwargs):
        # Get tech for this user
        site_user = SiteUser.objects.get(user=bundle.request.user)

        # Override the tech and operator fields
        bundle.obj.tech = site_user
        bundle.obj.operator = site_user.operator

        super(ClientResource, self).obj_create(bundle, **kwargs)
但是,这似乎不起作用。使用PDB运行时,我可以将字段添加到bundle确定,但是当我让它运行时,我会发出以下错误:

  

{“error_message”:“(1048,\”列'operator_id'不能为空\“)”,   “traceback”:“Traceback(最近一次调用最后一次):\ n \ n文件   \ “/家/马修/项目/ MYPROJECT / VENV / local / lib目录/ python2.7 /站点包/ tastypie / resources.py \”,   第217行,在包装器中\ n response = callback(request,* args,   ** kwargs)\ n \ n File \“/ home / matthew / Projects / Myproject / venv / local / lib / python2.7 / site-packages / tastypie / resources.py \”,   第459行,在dispatch_list \ n中返回self.dispatch('list',request,   ** kwargs)\ n \ n File \“/ home / matthew / Projects / Myproject / venv / local / lib / python2.7 / site-packages / tastypie / resources.py \”,   第491行,在dispatch \ n response = method(request,** kwargs)\ n \ n文件   \ “/家/马修/项目/ MYPROJECT / VENV / local / lib目录/ python2.7 /站点包/ tastypie / resources.py \”,   第1357行,在post_list \ n updated_bundle = self.obj_create(bundle,   ** self.remove_api_resource_names(kwargs))\ n \ n File \“/ home / matthew / Projects / Myproject / app_api / api.py \”,第49行,in   obj_create \ n super(ClientResource,self).obj_create(bundle,   ** kwargs)\ n \ n File \“/ home / matthew / Projects / Myproject / venv / local / lib / python2.7 / site-packages / tastypie / resources.py \”,   第2150行,在obj_create \ n中返回self.save(包)\ n \ n文件   \ “/家/马修/项目/ MYPROJECT / VENV / local / lib目录/ python2.7 /站点包/ tastypie / resources.py \”,   第2296行,在save \ n bundle.obj.save()\ n \ n文件中   \ “/家/马修/项目/ MYPROJECT / VENV / local / lib目录/ python2.7 /站点包/ Django的/ DB /模型/ base.py \”,   第546行,在save \ n force_update = force_update中,   update_fields = update_fields)\ n \ n文件   \ “/家/马修/项目/ MYPROJECT / VENV / local / lib目录/ python2.7 /站点包/ Django的/ DB /模型/ base.py \”,   第650行,在save_base \ n result = manager._insert([self],   fields = fields,return_id = update_pk,using = using,raw = raw)\ n \ n文件   \ “/家/马修/项目/ MYPROJECT / VENV / local / lib目录/ python2.7 /站点包/ Django的/ DB /模型/ manager.py \”,   第215行,在_insert \ n中返回insert_query(self.model,objs,fields,   ** kwargs)\ n \ n File \“/ home / matthew / Projects / Myproject / venv / local / lib / python2.7 / site-packages / django / db / models / query.py \”,   第1661行,在insert_query \ n返回   query.get_compiler(using = using).execute_sql(return_id)\ n \ n文件   \ “/家/马修/项目/ MYPROJECT / VENV / local / lib目录/ python2.7 /站点包/ Django的/ DB /模型/ SQL / compiler.py \”,   第937行,在execute_sql \ n cursor.execute(sql,params)\ n \ n文件中   \ “/家/马修/项目/ MYPROJECT / VENV / local / lib目录/ python2.7 /站点包/ Django的/ DB /后端/ util.py \”,   第41行,执行\ n返回self.cursor.execute(sql,params)\ n \ n文件   \ “/家/马修/项目/ MYPROJECT / VENV / local / lib目录/ python2.7 /站点包/ Django的/ DB /后端/ mysql /下base.py \”,   第127行,执行\ n six.reraise(utils.IntegrityError,   utils.IntegrityError(* tuple(e.args)),sys.exc_info()[2])\ n \ n文件   \ “/家/马修/项目/ MYPROJECT / VENV / local / lib目录/ python2.7 /站点包/ Django的/ DB /后端/ mysql /下base.py \”,   第120行,执行\ n返回self.cursor.execute(query,args)\ n \ n   文件   \ “/家/马修/项目/ MYPROJECT / VENV / local / lib目录/ python2.7 /站点包/ MySQLdb的/ cursors.py \”,   第201行,执行\ n self.errorhandler(self,exc,value)\ n \ n文件   \ “/家/马修/项目/ MYPROJECT / VENV / local / lib目录/ python2.7 /站点包/ MySQLdb的/ connections.py \”,   第36行,在defaulterrorhandler \ n引发错误类,   errorvalue \ n \ nIntegrityError:(1048,\“列'operator_id'不能   空\ “)\ n” 个}

我在添加字段后尝试使用和不使用bundle.obj.save(),但似乎没有任何区别。

obj_create是否覆盖这些值的正确位置?如果是这样,任何人都可以指出我出错的地方。如果没有,我应该在哪里看?

1 个答案:

答案 0 :(得分:1)

如果有人发现这个,我找到了解决方案。最简单的方法就是用一个新方法覆盖obj_create方法,如下所示:

def obj_create(self, bundle, **kwargs):
    # Get tech for this user
    site_user = SiteUser.objects.get(user=bundle.request.user)

    bundle.obj = self._meta.object_class()

    for key, value in kwargs.items():
        setattr(bundle.obj, key, value)

    # Override the tech and operator fields
    setattr(bundle.obj, 'tech', site_user)
    setattr(bundle.obj, 'operator', site_user.operator)

    self.authorized_create_detail(self.get_object_list(bundle.request), bundle)
    bundle = self.full_hydrate(bundle)
    return self.save(bundle);