Django global variable for base.html

吃可爱长大的小学妹 提交于 2021-01-28 06:16:35

问题


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>
  1. I'm not really sure if its implemented the right way.
  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!