2010-09-15 25 views
5

Czytam ostateczny przewodnik do django i jestem w rozdziale 4 na temat dziedziczenia szablonów. Wydaje się, że nie robię czegoś tak eleganckiego, jak to tylko możliwe, ponieważ muszę skopiować kod, aby kontekst pojawił się podczas wywoływania widoku podrzędnego. Oto kod w views.py:Dziedziczenie i kontekst szablonu django

def homepage(request): 
    current_date = datetime.datetime.now() 
    current_section = 'Temporary Home Page' 
    return render_to_response("base.html", locals()) 
def contact(request): 
    current_date = datetime.datetime.now() 
    current_section = 'Contact page' 
    return render_to_response("contact.html", locals()) 

Wydaje się zbędne, aby w każdej funkcji uwzględnić linię current_date.

Oto plik html że baza głównej połączenia:

<html lang= "en"> 
<head> 
    <title>{% block title %}Home Page{% endblock %}</title> 
</head> 
<body> 
    <h1>The Site</h1> 
    {% block content %} 
     <p> The Current section is {{ current_section }}.</p> 
    {% endblock %} 

    {% block footer %} 
    <p>The current time is {{ current_date }}</p> 
    {% endblock %} 
</body> 
</html> 

i plik szablonu dziecko:

{% extends "base.html" %} 

{% block title %}Contact{% endblock %} 

{% block content %} 
<p>Contact information goes here...</p> 
    <p>You are in the section {{ current_section }}</p> 
{% endblock %} 

Gdybym nie zawierają CURRENT_DATE linię podczas wywoływania pliku dziecięcą, gdzie ta zmienna powinna pojawić się jest pusta.

Odpowiedz

16

Możesz przekazać zmienną do każdego szablonu za pomocą Context Processor:

1. Dodanie procesora kontekstowe złożyć

pierwsze ustawienia, trzeba będzie dodać niestandardowej Context procesora do settings.py:

# settings.py 

TEMPLATE_CONTEXT_PROCESSORS = (
    'myapp.context_processors.default', # add this line 
    'django.core.context_processors.auth', 
) 

z tego można wyprowadzić, że będzie trzeba utworzyć moduł o nazwie context_processors.py i umieścić go wewnątrz aplikacji fol der. Możesz dalej zobaczyć, że będzie trzeba zadeklarować funkcję o nazwie default (jak to jest zawarte w settings.py), ale jest to dowolne. Możesz wybrać dowolną nazwę funkcji, którą preferujesz.

2. Tworzenie procesora Context

# context_processors.py 

from datetime import datetime 
from django.conf import settings # this is a good example of extra 
            # context you might need across templates 
def default(request): 
    # you can declare any variable that you would like and pass 
    # them as a dictionary to be added to each template's context: 
    return dict(
     example = "This is an example string.", 
     current_date = datetime.now(),     
     MEDIA_URL = settings.MEDIA_URL, # just for the sake of example 
    ) 

3. Dodawanie dodatkowy kontekst do swoich poglądów

Ostatnim etapem jest przetwarzanie dodatkowy kontekst korzystania RequestContext() i przekazać je do szablonu jako zmienną . Poniżej znajduje się bardzo uproszczony przykład tego rodzaju modyfikacji pliku views.py która byłaby wymagana:

# old views.py 
def homepage(request): 
    current_date = datetime.datetime.now() 
    current_section = 'Temporary Home Page' 
    return render_to_response("base.html", locals()) 

def contact(request): 
    current_date = datetime.datetime.now() 
    current_section = 'Contact page' 
    return render_to_response("contact.html", locals()) 


# new views.py 
from django.template import RequestContext 

def homepage(request): 
    current_section = 'Temporary Home Page' 
    return render_to_response("base.html", locals(), 
           context_instance=RequestContext(request)) 

def contact(request): 
    current_section = 'Contact page' 
    return render_to_response("contact.html", locals(), 
           context_instance=RequestContext(request)) 
3

Tak, można użyć django.views, generic.simple.direct_to_template zamiast render_to_response. Wykorzystuje wewnętrznie RequestContext.

from django.views,generic.simple import direct_to_template 

def homepage(request): 
    return direct_to_template(request,"base.html",{ 
     'current_section':'Temporary Home Page' 
    }) 

def contact(request): 
    return direct_to_template(request,"contact.html",{ 
     'current_section':'Contact Page' 
    }) 

Lub można nawet określić go bezpośrednio na urls.py takich jak

urlpatterns = patterns('django.views.generic.simple', 
    (r'^/home/$','direct_to_template',{ 
     'template':'base.html' 
     'extra_context':{'current_section':'Temporary Home Page'},   
    }), 
    (r'^/contact/$','direct_to_template',{ 
     'template':'contact.html' 
     'extra_context':{'current_section':'Contact page'},   
    }), 
0

Dla django v1.8 + zmiennych zwracany wewnątrz context processor mogą być dostępne.

1. Dodaj procesor kontekstowe do listy TEMPLATES wewnątrz settings.py

TEMPLATES = [ 
    { 
     'BACKEND': 'django.template.backends.django.DjangoTemplates', 
     'DIRS': [], 
     'APP_DIRS': True, 
     'OPTIONS': { 
      'context_processors': [ 
       'django.template.context_processors.debug', 
       'django.template.context_processors.request', 
       'django.contrib.auth.context_processors.auth', 
       'django.contrib.messages.context_processors.messages', 

       'your_app.context_processor_file.func_name', # add this line 

      ], 
     }, 
    }, 
] 

2.Utwórz nowy plik dla procesora kontekstowego i zdefiniować metodę kontekście

context_processor_file.py

def func_name(request): 
    test_var = "hi, this is a variable from context processor" 
    return { 
    "var_for_template" : test_var, 
    } 

3. Teraz można uzyskać var_for_template w dowolnych szablonów

na przykład dodać tę linię wewnątrz: base.html

<h1>{{ var_for_template }}</h1> 

to uczyni:

<h1>hi, this is a variable from context processor</h1>

celu zaktualizowania szablonów Django 1.8+ śledzić this django doc