1

This is an issue I have been struggling with for a long time, so posting it on here hoping for some guidance.

When I am creating a new child instance of an item, I am struggling to pass the pk value from the parent, so the child instance is created under the correct parent.

Parent Models.py

class listofbooks(models.Model):
    booktitle = models.CharField(max_length = 100)
    description = models.TextField(null=True) 

Child Models.py

class author(models.Model):
    listofbooks = models.ForeignKey("books.listofbooks",on_delete=models.CASCADE, blank=True, null=True)
    authorname= models.CharField(max_length = 100, null=True)
    authorage = models.IntegerField()

Parent urls.py

app_name = 'books'
urlpatterns = [
    path('', BookListView.as_view(), name='book-list-view'),
    path('new/', BookCreateView.as_view(), name='book-create'),    
    path('<int:listofbooks_pk>/', BookDetailView.as_view(), name='book-detail'),
]

Child urls.py

app_name = 'author'
urlpatterns = [
    path('<int:listofbooks_pk>/authors', AuthorListView.as_view(), name='author-list'),
    path('<int:author_pk>', AuthorInfoView.as_view(), name='author-detail'),
    path('<int:listofbooks_pk>/new/', AuthorCreateView.as_view(), name='author-create'),
]

Child views.py

class AuthorInfoView(DetailView):
    model = author
    pk_url_kwarg = "author_pk"

class AuthorListView(ListView):
    model = author
    pk_url_kwarg = "author_pk"

context_object_name = 'listofauthors'

def get_queryset(self, *args, **kwargs):
    return author.objects.filter(listofbooks=self.kwargs['listofbooks_pk'])

class AuthorCreateView(CreateView):
    model = author
    pk_url_kwarg = "listofbooks_pk"
    fields = ['authorname','authorage']

    def get_success_url(self, *args, **kwargs):
        return reverse('author:author-detail',kwargs={'author_pk':self.object.pk})

Here is the author_list.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>This is the list of Authors page</h1>
    {% for item in listofauthors %} <br>
        {{ item.authorname }} <br>
        {{ item.authorage }} <br>
        <a href = "{% url 'author:author-detail' item.id %}">View Author Detail</a> <br>
    {% endfor %}

    <a href = "{% url 'author:author-create' object.id %}" >Add Author</a> <br>

</body>
</html>

Error Message

NoReverseMatch at /author/1/authors
Reverse for 'author-create' with arguments '('',)' not found. 1 pattern(s) tried: ['author/(?P<listofbooks_pk>[0-9]+)/new/$']
Request Method: GET
Request URL:    http://192.168.1.70:8080/author/1/authors
Django Version: 3.0.3
Exception Type: NoReverseMatch
Exception Value:    
Reverse for 'author-create' with arguments '('',)' not found. 1 pattern(s) tried: ['author/(?P<listofbooks_pk>[0-9]+)/new/$']
Exception Location: /home/pi/test/venv/lib/python3.7/site-packages/django/urls/resolvers.py in _reverse_with_prefix, line 677
Python Executable:  /home/pi/test/venv/bin/python
Python Version: 3.7.3
Python Path:    
['/home/pi/test/booklist',
 '/home/pi/test/venv/lib/python37.zip',
 '/home/pi/test/venv/lib/python3.7',
 '/home/pi/test/venv/lib/python3.7/lib-dynload',
 '/usr/lib/python3.7',
 '/home/pi/test/venv/lib/python3.7/site-packages']
Server time:    Sun, 16 Feb 2020 19:56:08 +0000

If I replace this line in the author_list.html and force a number in there it works fine. So replace this

    <a href = "{% url 'author:author-create' object.id %}" >Add Author</a> <br>

with this

    <a href = "{% url 'author:author-create' 1 %}" >Add Author</a> <br>

My understanding is I need to get the listofbooks.pk value into where object.id is, but am now at a dead end as to how to resolve this.

  • It makes perfect sense that `Add Author
    ` can not be resolved (yet), since an object that is not created, has not yet a primary key.
    – Willem Van Onsem Feb 16 '20 at 20:14
  • Hi Willem, I was thinking the object.id relates to the parent item, so when a child item is created it is linked to the parent item. If I remove object.id i get the following error: Exception Type: NoReverseMatch Exception Value: Reverse for 'author-create' with no arguments not found. 1 pattern(s) tried: ['author/(?P[0-9]+)/new/$'] – Trevor Appleton Feb 16 '20 at 20:52
  • What does "parent item" mean? `AuthorListView` doesn't define `object` in the context so you need to figure out what that is supposed to be and pass it in `get_context_data` – markwalker_ Feb 16 '20 at 21:00
  • Hi Mark, in my models I have parent items which are listofbooks and child items which is author. When I am creating a new author, it needs to be linked to the relevant parent, which I described as parent item. From your answer though you point me to AuthorListView. So I need to pass the id of the parent item within AuthorListView? I will look how to do that using get_context_data. – Trevor Appleton Feb 16 '20 at 21:08
  • Still having no luck with this. I tried implementing ideas from this answer, but it doesnt seem to have made a difference. https://stackoverflow.com/questions/24978121/how-do-i-pass-a-parent-id-as-an-fk-to-child-objects-modelform-using-generic-cla I am sure if I can get the listofbooks.pk value and pass it into my objects.id in the author_list.html that will resolve the issue. – Trevor Appleton Feb 18 '20 at 21:18

0 Answers0