简体   繁体   中英

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 Issue s and Solutions s in the database, numbered 1 through 10
  • Loading the Issue via the DetailView (eg localhost:8000/myapp/6/ ) works great

Error

When trying to load the Solution view in a browser (eg 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?

Which Django Version did you use? try this...

urls.py

urlpatterns = [
    path('solution/<int:pk>/', SolutionView.as_view(), name='solution'),
]

views.py

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


    def get_object(self):
        some_pk = self.kwargs.get("pk")
        return get_object_or_404(Solution, pk=some_pk)

Tested. This works for me fine. It´s django 3.0 but i guess down to version 2.x this should also work.

you have to send the integer variable from your request to your class based view some_pk so that django can get the right object.

page not found relates also to your template path - so check it.

Don´t forget to set the right template_name and to import everything.

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.

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