Search code examples
pythondjangopython-3.xdjango-viewsdjango-generic-views

How can I solve this issue in django without changing the models?


Info

  • I have two simple models in Django, with one-to-one relationship
  • I'm using generic views
  • There are Issues and Solutionss in the database, numbered 1 through 10
  • Loading the Issue via the DetailView (e.g. localhost:8000/myapp/6/) works great

Error

When trying to load the Solution view in a browser (e.g. localhost:8000/myapp/6/solution/), I get Page not found (404), No solution found matching the query.

Code

models.py:

class Issue(models.Model):
    def __str__(self):
        return self.issue_text
    issue_text = models.CharField(max_length=200)

class Solution(models.Model):
    def __str__(self):
        return self.solution_text
    issue = models.OneToOneField(Issue, on_delete=models.CASCADE)
    solution_text = models.CharField(max_length=200)

views.py:

class DetailView(generic.DetailView):
    model = Issue
    template_name = 'my_templates/detail.html'

class SolutionView(generic.DetailView):
    model = Solution
    template_name = 'my_templates/solution.html'

urls.py:

urlpatterns = [
    url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
    url(r'^(?P<pk>[0-9]+)/solution/$', views.SolutionView.as_view(), name='solution'),
]

Question

I suspect that maybe the relationship between the models is incorrect - I can see that the view raises the 404 error because it can't find a solution object (though there are a few solution objects in the database, for every Issue).

I've been going through Django's docs on generic views and making Django queries to the database but I think I'm confusing the two.

Also, debugging with pdb just makes the browser lose the object for some reason.

Did I get the one-to-one relationship wrong?


Solution

  • There was a mismatch between the app name and the object instance.

    In this case, the app, the module and the model objects were named differently. For example - following django's tutorial: the name of the app should be polls and the templates sub-directory should also be polls/templates/polls, but in this case the app was named something like polls_app and the templates sub-directory something like polls_templates. Any other naming mismatch results in the same way.

    I found this while trying to run tests in django - even though everything else worked (other than this specific, generic view), the tests failed with an error. Investigating that error led me to the tests runner code (see here or here) and loadTestsFromName in it.

    So I guess that django relies on the object name (in the example above - it was searching for polls in polls_templates or something similar), but I couldn't find how this can be configured. Trying to debug it with pdb wans't great either, since I was getting way deep into django's source code.

    I created a new app, with everything named the same, and now tests are running ok, and also the SolutionView, so having everything called by the same name solved the question for me.

    I assume that there's a similar name-relying module in django's url which does the same thing.