Django - 将外键传递给第二个模型

时间:2018-05-06 04:40:23

标签: python django python-3.x

我正在尝试为django webapp创建一个相当简单的输入视图。我有以下简单的模型设置。最后我还包括了追溯。问题是我如何在CreateView类中创建一个对象并传递父对象的外键?

#models.py
#imports...

class Client(models.Model):

    client_id = models.AutoField(
        primary_key=True)

class Item(models.Model):

    client = models.ForeignKey(
        Client,
        on_delete=models.CASCADE)
    item_id = models.AutoField(
        primary_key=True)

我们的想法是拥有一个唯一客户列表,然后每个客户端都可以拥有一个唯一项列表。这些项目链接到客户端。

#views.py
#imports...

class ItemCreate(CreateView):
    model = Item
    fields = [
        #list of fields
        ]

    def form_valid(self, form):
        form.instance.client_id = self.request.client.client_id
        return super(PermCreate, self).form_valid(form)

鉴于这两个类模型,我正在尝试CreateView创建一个新的Item并将其附加到相应的Client。我有一个ListView,它将针对给定的Items迭代ClientListView有一个指向CreateView(添加新项)的链接。我对观看中的pk没有问题,甚至没有问CreateView。我无法让CreateView保存对象。我得到一个错误,说......

'WSGIRequest' object has no attribute 'client'

上面的代码源自this问题。我已经尝试了几次迭代的参数来设置form.instance.client_id但是request可能是错误的调用。给出的示例使用user调用本身不是表外键信息。

我也尝试了this(使用我的模型的主键)并且我已经厌倦了从模板标签访问URL pk - 但是想想我是否无法在views对象中访问它们从模板中获取会更加困难。

回溯

File "/anaconda3/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  35.             response = get_response(request)

File "/anaconda3/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  128.                 response = self.process_exception_by_middleware(e, request)

File "/anaconda3/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/anaconda3/lib/python3.6/site-packages/django/views/generic/base.py" in view
  69.             return self.dispatch(request, *args, **kwargs)

File "/anaconda3/lib/python3.6/site-packages/django/views/generic/base.py" in dispatch
  89.         return handler(request, *args, **kwargs)

File "/anaconda3/lib/python3.6/site-packages/django/views/generic/edit.py" in post
  172.         return super().post(request, *args, **kwargs)

File "/anaconda3/lib/python3.6/site-packages/django/views/generic/edit.py" in post
  142.             return self.form_valid(form)

File "/Users/billarmstrong/Documents/GitHub/Core/WebDataCollect/Pro/ProWP/views.py" in form_valid
  55.         form.instance.client_id = self.request.client.client_id

Exception Type: AttributeError at /ProWP/2/additem/
Exception Value: 'WSGIRequest' object has no attribute 'client'

更新

# urls.py

    path('<int:pk>/additem/', views.ItemCreate.as_view(), name='item-add'),
    path('<int:pk>/item/', views.ItemView.as_view(), name='itemview'),

我也取得了一些进展。我已经开始使用示例1代码,发现如果我设置form.instance.client_id = 2它将适当地添加具有2外键的对象。所以问题是尝试获取原始POST pk。我已经尝试了示例2并抛出了(1048, "column 'client_id' cannot be null"),我将其解释为意味着我没有得到Item对象。所以,我尝试了示例3和(1048, "Column 'client_id' cannot be null")

# views.py
# Example 1

    def form_valid(self, form):
        form.instance.client_id = 2
        return super(PermCreate, self).form_valid(form)

# Example 2

    def form_valid(self, form):
        pk = self.kwargs.get("perm_id", None)
        form.instance.client_id = pk
        return super(PermCreate, self).form_valid(form)


# Example 3

    def form_valid(self, form):
        pk = self.kwargs.get("client_id", None)
        form.instance.client_id = pk
        return super(PermCreate, self).form_valid(form)

更新2

经过测试和print - 我认为问题出在我的requestkwargs.get变量中。由于整个事情在我对实例中的client_id进行硬编码时起作用 - 我得出的结论是实例确实存在所有适当的信息 - 包括URL主键 - 但我没有得到正确的变量名称来访问它。我知道它不是item_idclient_id

更新3

requestKWARGS都有效。在完成每个可能的变量以获得主键后,结果是pk

因此,不是使用client_iditem_id,而是将值保存在pk中。任何解释都会有所帮助。我猜这个URL实际上是从我的urls.py文件设置变量 - 但不是100肯定。

1 个答案:

答案 0 :(得分:1)

form.instance.client_id = self.request.client.client_id

这一行应该是,

form.instance.client_id = self.request.POST['client'].client_id

form.instance.client_id = self.request.GET['client'].client_id

取决于请求类型。