0

在我的一个观点中,我定义了一个 mixin 来根据用户的会话详细信息动态设置多个模型(包括 Client 模型)的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 运行它时,我可以将字段添加到bundleOK,但是当我让它运行时,它会吐出以下错误:

{"error_message": "(1048, \"Column 'operator_id' cannot be null\")", "traceback": "Traceback (last last last call):\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 File \ “/home/matthew/Projects/Myproject/venv/local/lib/python2.7/site-packages/tastypie/resources.py\”,第 459 行,在 dispatch_list\n return self.dispatch('list', request, **kwargs)\n\n 文件 \"/home/matthew/Projects/Myproject/venv/local/lib/python2.7/site-packages/tastypie/resources.py\",第 491 行,在调度中\n 响应= 方法(请求,**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 行,在 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 return self.save(bundle)\n\n File \"/home/matthew/Projects/ Myproject/venv/local/lib/python2.7/site-packages/tastypie/resources.py\",第 2296 行,在 save\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 文件\"/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 return 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 行,在执行中\n Six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[ 2])\n\n 文件\"/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 文件 \"/home/matthew/Projects/Myproject/venv/local/lib/python2.7/site-packages/MySQLdb/cursors.py \",第 201 行,在执行中\n self.errorhandler(self, exc,值)\n\n 文件 \"/home/matthew/Projects/Myproject/venv/local/lib/python2.7/site-packages/MySQLdb/connections.py\",第 36 行,在 defaulterrorhandler\n 引发错误类, errorvalue\n\nIntegrityError: (1048, \"Column 'operator_id' cannot be null\")\n"}

添加字段后,我尝试了使用和不使用 bundle.obj.save() ,但似乎没有什么不同。

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

4

1 回答 1

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);
于 2013-07-13T12:45:21.313 回答