Reputation: 1777
I'm trying to create a fairly simply input view for a django webapp. I have the following simply models set up. At the end I've included the traceback as well. The question is how do I create an object in the CreateView class and pass the foreign key of the parent object?
#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)
The idea is to have a list of unique clients and then each client can have a list of unique items. The items are linked to the client.
#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)
Given these two class models, I'm trying to CreateView
that will create a new Item
and have it attached to the respective Client
. I have a ListView
that will iterate through Items
for a given Client
. The ListView
has a link to the CreateView
(Add New Item). I am not having a problem with the pk
's in the views or even getting to the CreateView
. I can't get the CreateView
to save the object. I get an error that says...
'WSGIRequest' object has no attribute 'client'
The code above is derived from this question. I've tried several iterations of the argument to set form.instance.client_id
but a request
is likely the wrong call. The examples given are using user
calls not per se the table foreign key information.
I've also tried this (using the primary keys for my models) and I've tired accessing the URL pk from the template tags - but figured if I can't access them in the the views object that getting from the template would be more difficult.
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'),
I've also made some progress. I've started working with example 1 code and found that if I set form.instance.client_id = 2
that it will appropriately add the object with the foreign key of 2
. So the issue is trying to get the originating POST pk
. I've tried example 2 and it throws (1048, "column 'client_id' cannot be null")
which i interpret to mean that I'm not getting the Item
object. So, I tried example 3 and (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)
after testing and print
ing - I think the issue is in my request
or kwargs.get
variable. Since the entire thing works when I hard code the client_id
in the instance - I've concluded that the instance does in fact exist with all the appropriate information - including the URL primary key - but I'm not getting the right variable name to access it. I know it isn't item_id
or client_id
.
Both request
and KWARGS
work. After working through every possible variable to get to the primary key it turned out to be pk
.
So rather than using either the client_id
or the item_id
, the value is held in pk
. Any explanation would be helpful. I'm guessing that the URL actually sets the variable from my urls.py
file - but not 100 certain.
Upvotes: 0
Views: 1610
Reputation: 8398
form.instance.client_id = self.request.client.client_id
this line should be like,
form.instance.client_id = self.request.POST['client'].client_id
or
form.instance.client_id = self.request.GET['client'].client_id
Depending upon request type.
Upvotes: 1