Django fortune teller

I’m on the fortuneteller challenge for Django and I wanted to created another view function for the fortune.html template so i coded this:

from django.shortcuts import render
import random

# Create your views here.
fortuneList = [
  "Today is a good day to wear blue",
  "You should drink more apple juice",
  "You are getting that job soon",
  "You should trust yourself more",
  "Eat healthier food is gonna make you feel better"
]
horoscopeList = [
  "If you want to succed work hard",
  "You are going to have a romantic date this week",
  "This is a good week to spend time with friends and family",
  "Blue is your lucky color",
  "Your lucky number for this week is 13"
]
def fortune(request):
  fortune = random.choice(fortuneList)
  context_1 = {"fortune": fortune}
  return render(request,'randomfortune/fortune.html', context_1)
def horoscope(request):
  horoscope = random.choice(horoscopeList)
  context_2 = {"horoscope": horoscope}
  return render(request, 'randomfortune/fortune.html', context_2)

But when I run the server its showing only the first context. Can someone help me?

My urls.py files are like this:

from django.urls import path
from . import views

urlpatterns = [
  path("", views.fortune, name = 'fortune'),
  path("", views.horoscope, name = 'horoscope')
  
]

And:

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls),
    path("", include("randomfortune.urls")),
    path("", include("randomfortune.urls"))
]
1 Like

Your problem is you have assigned both views to the same blank url path. This is not possible in Django as each view needs to have a unique URL to access it. If you think about it, django has know way of knowing which exact view you want at whatever time you may access that URL, because it’s programmed to only serve one view.
However, notice that the context we added in the fortune view is a data dictionary. This means that we can actually have more than 1 key-value pair! So instead of what you have right now, you can have a single view that serves both as context, like so:

def fortune(request):
   fortune = random.choice(fortuneList)
   horoscope = random.choice(horoscopeList)
   context = {"fortune": fortune, "horoscope": horoscope}
   return render(request, 'randomfortune/fortune.html, context)

and then you can access fortune and horoscope in the template independently by using the keys. Then your app-level urls.py should look like below:

from django.urls import path
from . import views

urlpatterns = [
   path("", views.fortune, name='fortune'),
]

if you really wanted them to be two different views, then you would just serve your second view from a different path, for example below:

from django.urls import path
from . import views

urlpatterns = [
  path("fortune", views.fortune, name = 'fortune'),
  path("horoscope", views.horoscope, name = 'horoscope')
  

And then when you go to localhost:8000/fortune you get the original, and localhost:8000/horoscope you get the new horoscope page.

Also worth pointing out that here

You have included the path to randomfortune.urls twice. This is not required as it essentially is a reference to your entire urls.py in your app, and as such all urls will be available on your entire domain. You rarely need to add extra urls to your project-wide urls.py, you simply include the app.urls once and then add any app-level urls to the relevant urls.py.

Hope that all made sense and it helps you understand views a little more!

2 Likes

Your explanation was just perfect!! It really helped me understanding, thank you so much! :slight_smile:

1 Like

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.