问题
i've implemented a global variable but i dont really know how to access it. The examples i have found are a bit confusing.
models.py
...
# Categorys of Post Model
class Category(models.Model):
title = models.CharField(max_length=255, verbose_name="Title")
class Meta:
verbose_name = "Category"
verbose_name_plural = "Categories"
ordering = ['title']
def __str__(self):
return self.title
#Post Model
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField(max_length=10000)
category = models.ForeignKey(Category, verbose_name="Category", on_delete=models.CASCADE, null=True)
...
settings.py:
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"Post.global.category_dropdown",
)
global.py
from .models import Category
def category_dropdown(request):
categories = Category.objects.all()
return {'categories': categories}
base.html:
<body>
<div class="page-header">
<form method="POST">
<label>
<select name="Category">
{% for global in category_dropdown %}
<option value="{{ categorie.title }}">{{ categorie.title }} {{ categorie.post_set.count }}</option>
{% endfor %}
</select>
</label>
</form>
- I'm not really sure if its implemented the right way.
- I don't know how to access the global var. in Template
In the end this should display a dropdown menu in the header of every page wich gets his value from the database as you can see in models.py
thanks in advance
回答1:
EDIT:
I see what you want. I think you are very close to a solution, and what you found is very similar to my previous answer. The main difference is, that you inject context in a global.py
file with TEMPLATE_CONTEXT_PROCESSOR
.
So with TEMPLATE_CONTEXT_PROCESSORS
you inject the context variables in your context dictionary. For example, if you have Form then your context looks like:
{
'form': {
...
}
}
in your case you always inject the parameter categories
inside so your context looks like:
{
'form': {
...
},
'categories': [
{
'title': 'your title 1'
'posts': [...]
},
{
'title': 'your title 2'
'posts': [...]
},
....
]
}
So what you could do is access this context variable inside your HTML code.
<body>
<div class="page-header">
<form method="POST">
<label>
<select name="Category">
{% for category in categories %}
<option value="{{ category.title }}">{{ category.title }} {{ category.post_set.count }}</option>
{% endfor %}
</select>
</label>
</form>
Because the name of the variable in dictionary is 'category', (and contains array of your categories) you should access this variable in your for loop. When you iterate trough categories you create temporary variable named category (or any other name) and use this variable to access title and number of posts.
PREVIOUS:
I am not sure what you are asking for.
But what you probably need is to have category list always inside your context_data
.
This mean that you can prepare some function that fetch all Category and create context from it like :
def prepare_category_context(context_data):
"""
Function that create context data for all Views classes.
"""
context_data['categories'] = model.Category.objects.all()
return context_data
class myView(generic.EnyViewClass):
"""
Example of the View Class. This could be generic.TemplateView, CreateView,...
The trick is to add context data inside class.
"""
def get_context_data(self, **kwargs):
"""
Here we defined context data that will be used in templates.
We call our function here. But we need to call super first, if we have some form data or any thing else already in context...
"""
context = super().get_context_data(**kwargs)
context = self.prepare_category_context(context)
return context
来源:https://stackoverflow.com/questions/50586616/django-global-variable-for-base-html