0

Somehow my program generated two slashes // when I tried to add a new Menu item. Don't know how to fix that

Page not found (404)

Request Method:POSTRequest URL:http://127.0.0.1:8000/restaurant/menu/desserts-menu//add_menuItem/

Using the URLconf defined in WAD_Group_Project.urls, Django tried these URL patterns, in this order:

  1. [name='index']

  2. restaurant/ [name='index']

  3. restaurant/ about/ [name='about']

  4. restaurant/ menu/<slug:menu_name_slug>/add_menu_item/ [name='add_menu_item']

  5. restaurant/ menu/<slug:menu_name_slug>/ [name='show_menu']

  6. restaurant/ menu/<slug:menu_name_slug>/<slug:menuItem_name_slug>/ [name='show_menu_item']

  7. restaurant/ add_menu/ [name='add_menu']

  8. restaurant/ menu/<slug:menu_name_slug>/<slug:menuItem_name_slug>/add_review/ [name='add_review']

  9. restaurant/ restricted/ [name='restricted']

  10. admin/

  11. accounts/

  12. ^media/(?P<path>.*)$

The current path, restaurant/menu/desserts-menu//add_menuItem/, didn't match any of these.

You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.

Urls.py

from django.urls import path
from restaurant import views
app_name = 'restaurant'

urlpatterns = [
    path('', views.index, name='index'),
    path('about/', views.about, name = 'about'),
    path('menu/<slug:menu_name_slug>/add_menu_item/', views.add_menu_item, name='add_menu_item'),
    path('menu/<slug:menu_name_slug>/', views.show_menu, name='show_menu'),
    path('menu/<slug:menu_name_slug>/<slug:menuItem_name_slug>/', views.show_menu_item, name='show_menu_item'),
    #Template shows form but without any functionality
    path('add_menu/', views.add_menu, name="add_menu"),
    path('menu/<slug:menu_name_slug>/<slug:menuItem_name_slug>/add_review/', views.add_review, name="add_review"),
    path('restricted/', views.restricted, name='restricted'),
]

Views.py

def show_menu(request,menu_name_slug):
    context_dict = {}
    try:
        menu = Menu.objects.get(slug=menu_name_slug)
        menuItems = MenuItem.objects.filter(menu=menu)
        context_dict['menuItems'] = menuItems
        context_dict['menu'] = menu
    except Menu.DoesNotExist:
        context_dict['menu'] = None
        context_dict['menuItems'] = None

    return render(request, 'restaurant/menu.html', context=context_dict)

def show_menu_item(request, menu_name_slug, menuItem_name_slug):
    context_dict = {}
    
    try:
        menu = Menu.objects.get(slug=menu_name_slug)
        menuItem = MenuItem.objects.get(slug=menuItem_name_slug)
        reviews = Review.objects.filter(menuItem=menuItem)
        context_dict['reviews'] = reviews
        context_dict['menuItem'] = menuItem
        context_dict['menu'] = menu
    except Menu.DoesNotExist:
        context_dict['menu'] = None
        context_dict['menuItem'] = None
        context_dict['reviews'] = None

    return render(request, 'restaurant/menu_item.html', context=context_dict)

@login_required
def add_menu_item(request, menu_name_slug):
    try:
        menu = Menu.objects.get(slug=menu_name_slug)
    except Menu.DoesNotExist:
        menu = None
    if menu is None:
        return redirect('/restaurant/')
    form = MenuItemForm()
    if request.method == 'POST':
        form = MenuItemForm(request.POST)
        if form.is_valid():
            if menu:
                menuItem = form.save(commit=False)
                menuItem.menu = menu
                menuItem.save()
                return redirect(reverse('restaurant:show_menu', kwargs={'menu_name_slug': menu_name_slug}))
        else:
            print(form.errors)

    context_dict = {'form': form, 'menu': menu}
    return render(request, 'restaurant/add_menuItem.html', context=context_dict)

@login_required
def add_review(request, menu_name_slug, menuItem_name_slug):
    try:
        menuItem = MenuItem.objects.get(slug=menuItem_name_slug)
    except MenuItem.DoesNotExist:
        menuItem = None
    if menuItem is None:
        return redirect('/restaurant/')
    form = ReviewForm()
    if request.method == 'POST':
        form = ReviewForm(request.POST)
        if form.is_valid():
            if menuItem:
                review = form.save(commit=False)
                review.menuItem = menuItem
                review.save()
                return redirect(reverse('restaurant:show_menu_item', kwargs={'menuItem_name_slug': menuItem_name_slug}))
        else:
            print(form.errors)

    context_dict = {'form': form, 'menuItem': menuItem}
    return render(request, 'restaurant/add_review.html', context=context_dict)



Models.py
    class Menu(models.Model):
        MENU_ID_MAX_LENGTH=128
        menuID = models.TextField(max_length=MENU_ID_MAX_LENGTH,unique=True) # primary key
        slug = models.SlugField(unique=True)
        def save(self, *args, **kwards):
            self.slug = slugify(self.menuID)
            super(Menu, self).save(*args, **kwards)
        def __str__(self):
            return self.menuID
        
    class MenuItem(models.Model):
        MENUITEM_ID_MAX_LENGTH=128
        DESCRIPTION_MAX_LENGTH=200
        menuItemID = models.CharField(max_length=MENUITEM_ID_MAX_LENGTH, unique=True) # primary key 
        menu = models.ForeignKey(Menu, on_delete=models.CASCADE) # foreign key: one to many - many menu items for one menu
        description = models.CharField(max_length=DESCRIPTION_MAX_LENGTH, default="None")
        price = models.FloatField(default =0.0)
        photo = models.ImageField(upload_to='menu_item_images', blank=True)
        slug = models.SlugField(unique=True)
        def save(self, *args, **kwards):
            self.slug = slugify(self.menuItemID)
            super(MenuItem, self).save(*args, **kwards)
        class Meta:
            verbose_name_plural = 'MenuItems'
        def __str__(self):
            return self.menuItemID
        
    class Review(models.Model):
        REVIEW_ID_MAX_LENGTH=128
        COMMENT_MAX_LENGTH=1000
        reviewID =  models.CharField(max_length=REVIEW_ID_MAX_LENGTH, unique=True) # primary key 
        user = models.ForeignKey(User, on_delete=models.CASCADE) # foreign key: one to many - many reviews for one user 
        menuItem = models.ForeignKey(MenuItem, on_delete=models.CASCADE) # foreign key: one to many - many reviews for one menu item
        comment = models.CharField(max_length=COMMENT_MAX_LENGTH)
        ratings = models.IntegerField(default =0)
        photo = models.ImageField(upload_to='review_images', blank=True)
        def __str__(self):
            return self.reviewID
An K
  • 1
  • 2
  • Could it be the slug of your menu name? It could contain a redundant slash, share your model – SLDem Mar 22 '23 at 20:27
  • Or it could be a broken template with a partially hardcoded link. There's no `add_menuItem` anywhere in your code (just the name of a template). – Matthias Mar 22 '23 at 20:29
  • That was the problem with naming my third url (I did not have add_menuItem). Anyways, I tried to change that url to 'menu///add_menuItem/' and it started working, but I still wonder why Django generates that link with two slashes – An K Mar 22 '23 at 20:40
  • Also added models – An K Mar 22 '23 at 20:41

0 Answers0