使用Tastypie覆盖模型字段

在我的一个视图中,我定义了一个mixin来动态设置多个模型的 techoperator 字段,包括客户端模型,基于需要手动填充它们的用户's session details, so that a user didn't . 这个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 File \”/ home / matthew / Projects /Myproject/venv/local/lib/python2.7/site-packages/tastypie/resources.py \“,第217行,在包装器中\ n response = callback(request,* args,** kwargs)\ n \ n文件\“/ 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行,在发送中\ n response =方法(请求,** kwargs)\ n \ n文件\“/ home / matthew / Projects / Myproject / venv / local / lib / python2.7 / site-packages / 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文件\“/ home / matthew / Projects / Myproject / venv / local / lib / python2.7 / site-packages / tastypie / resources.py \”,第2150行,在obj_create \ n中return self.save(bundle)\ n \ n File \“/ home / matthew / Projects / Myproject / venv / local / lib / python2.7 / site-packages / tastypie / resources.py \”,第2296行,保存\ n bundle.obj.save()\ n \ n File \“/ home / matthew / Projects / Myproject / venv / local / lib / python2.7 / site-packages / django / db / models / base.py \” ,第546行,保存\ n force_update = force_update,update_fields = update_fields)\ n \ n文件\“/ home / matthew / Projects / Myproject / venv / local / lib / python2.7 / site-packages / django / db / models / base.py \“,第650行,在save_base \ n result = manager._insert([self],fields = fields,return_id = update_pk,using = using,raw = raw)\ n \ n File \”/ home /matthew/Projects/Myproject/venv/local/lib/python2.7/site-packages/django/db/models/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 File \”/ home / matthew / Projects / Myproject /venv/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py \“,第937行,在execute_sql \ n cursor.execute(sql,params)\ n \ n文件\ “/home/matthew/Projects/Myproject/venv/local/lib/python2.7/site-packages/django/db/backends/util.py \”,第41行,执行\ n返回self.cursor.execute( sql,params)\ n \ n File \“/ home / matthew / Projects / Myproject / venv / local / lib / python2.7 / site-packages / django / db / backends / mysql / base.py \”,第127行,在execute \ n six.reraise(utils.IntegrityError,utils.IntegrityError(* tuple(e.args)),sys.exc_info()[2])\ n \ n File \“/ home / matthew / Projects / Myproject /venv/local/lib/python2.7/site-packages/django/db/backends/mysql/base.py \“,第120行,在执行中\ n返回self.cursor.execute(query,args)\ n \ n File \“/ home / matthew / Projects / Myproject / venv / local / lib / python2.7 / site-packages / MySQLdb / cursors.py \”,li ne 201,执行\ n self.errorhandler(self,exc,value)\ n \ n File \“/ home / matthew / Projects / Myproject / venv / local / lib / python2.7 / site-packages / MySQLdb / connections .py \“,第36行,在defaulterrorhandler \ n引发错误类,错误值\ n \ nIntegrityError:(1048,\”列'operator_id'不能为空\“)\ n”}

在添加字段后,我已经尝试过使用和不使用bundle.obj.save(),但它似乎没有什么区别 .

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

回答(1)

2 years ago

如果有人发现这个,我找到了解决方案 . 最简单的方法是使用新的方法覆盖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);