如何在Django根模板base.html中展示自定义Button模型的所有对象?
Hey there! No worries about your English at all—let's fix this so you can display your buttons with proper HTML in your base template.
The issue right now is that your show_menu simple tag returns a QuerySet directly, which Django can't automatically render into formatted HTML. There are two common, straightforward ways to solve this:
Option 1: Modify the Simple Tag to Return Safe HTML
You can build the HTML string directly in your tag function, then tell Django it's safe to render without escaping. Here's how to update your menu_tags.py:
from django import template from django.utils.safestring import mark_safe # Add this import from menu.models import Button register = template.Library() @register.simple_tag def show_menu(): buttons = Button.objects.all() # Start building your HTML structure html_output = '<ul class="menu-buttons">' for button in buttons: # Add a CSS class if the button is required (button_corequise is True) required_class = 'required-button' if button.button_corequise else '' # Append each button's HTML html_output += f''' <li class="{required_class}"> <a href="{button.button_dirurl}">{button.button_name}</a> </li> ''' html_output += '</ul>' # Mark the string as safe so Django doesn't escape the HTML return mark_safe(html_output)
Then in your base.html, just use the tag like before (make sure you load the tags first):
{% load menu_tags %} <!-- Where you want the menu to appear --> {% show_menu %}
Option 2: Use an Inclusion Tag (Recommended)
This is a cleaner approach because it separates your HTML structure from the Python logic. You'll create a small template fragment for the menu, then use an inclusion tag to pass the button data to it.
First, update menu_tags.py to use an inclusion tag:
from django import template from menu.models import Button register = template.Library() @register.inclusion_tag('menu/menu_fragment.html') # Path to your template fragment def show_menu(): # Pass the buttons to the template as a context variable return {'buttons': Button.objects.all()}
Next, create a new template file at menu/templates/menu/menu_fragment.html (make sure your app has a templates directory set up):
<ul class="menu-buttons"> {% for button in buttons %} <li class="{% if button.button_corequise %}required-button{% endif %}"> <a href="{{ button.button_dirurl }}">{{ button.button_name }}</a> </li> {% empty %} <li>No buttons available</li> <!-- Fallback if there are no buttons --> {% endfor %} </ul>
Then use it in base.html the same way:
{% load menu_tags %} {% show_menu %}
Quick Notes:
- Make sure your
menuapp is added toINSTALLED_APPSinsettings.py—otherwise Django won't find your template tags. - The inclusion tag method is better for maintainability: if you want to change the menu's HTML later, you just edit the template fragment instead of messing with Python code.
Hope this helps you get your menu displaying exactly how you want it!
内容的提问来源于stack exchange,提问作者BronzoDev

