简体   繁体   中英

Django - Pass Foreign Key to Second Model

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.

Traceback

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'

Update

# 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)

Update 2

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 .

Update 3

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM