ฉันสามารถเข้าถึงค่าคงที่ใน settings.py จากเทมเพลตใน Django ได้หรือไม่


367

ฉันมีบางสิ่งใน settings.py ที่ฉันสามารถเข้าถึงได้จากเทมเพลต แต่ฉันไม่สามารถหาวิธีทำได้ ฉันลองแล้ว

{{CONSTANT_NAME}}

แต่ดูเหมือนจะไม่ทำงาน เป็นไปได้ไหม


หากคุณกำลังมองหาวิธีการส่งการตั้งค่าไปยังทุกคำตอบให้ดูที่คำตอบของ bchunn เกี่ยวกับตัวประมวลผลบริบท
Zags

1
คำตอบจาก @jkbrzt เป็นวิธีการแก้ปัญหาก่อนบรรจุซึ่งแก้ปัญหานี้ได้อย่างรวดเร็วและง่ายดาย ผู้อ่านในอนาคตควรดูที่stackoverflow.com/a/25841039/396005นี้สำหรับคำตอบที่ยอมรับ
Bron Davies

คำตอบ:


183

Django ให้การเข้าถึงค่าคงที่การตั้งค่าที่ใช้บ่อยบางอย่างกับแม่แบบเช่นsettings.MEDIA_URLและการตั้งค่าภาษาบางอย่างหากคุณใช้ django ที่สร้างขึ้นในมุมมองทั่วไปหรือส่งผ่านอาร์กิวเมนต์คำหลักอินสแตนซ์บริบทในrender_to_responseฟังก์ชันทางลัด นี่คือตัวอย่างของแต่ละกรณี:

from django.shortcuts import render_to_response
from django.template import RequestContext
from django.views.generic.simple import direct_to_template

def my_generic_view(request, template='my_template.html'):
    return direct_to_template(request, template)

def more_custom_view(request, template='my_template.html'):
    return render_to_response(template, {}, context_instance=RequestContext(request))

มุมมองเหล่านี้จะมีการตั้งค่าที่ใช้บ่อยหลายอย่างเช่นsettings.MEDIA_URLมีให้ในเทมเพลตเช่น{{ MEDIA_URL }}และอื่น ๆ

หากคุณกำลังมองหาการเข้าถึงค่าคงที่อื่น ๆ ในการตั้งค่าให้คลายค่าคงที่ที่คุณต้องการและเพิ่มลงในพจนานุกรมบริบทที่คุณใช้ในฟังก์ชั่นมุมมองของคุณเช่น:

from django.conf import settings
from django.shortcuts import render_to_response

def my_view_function(request, template='my_template.html'):
    context = {'favorite_color': settings.FAVORITE_COLOR}
    return render_to_response(template, context)

ตอนนี้คุณสามารถเข้าถึงแม่แบบของคุณเป็น settings.FAVORITE_COLOR{{ favorite_color }}


66
เป็นที่น่าสังเกตว่าค่าเฉพาะที่เพิ่มโดยใช้ RequestContext นั้นขึ้นอยู่กับค่าของ TEMPLATE_CONTEXT_PROCESSORS ดังนั้นหากคุณต้องการค่าเพิ่มเติมที่ส่งผ่านไปทุกที่เพียงแค่เขียนตัวประมวลผลบริบทของคุณเองและเพิ่มลงใน TEMPLATE_CONTEXT_PROCESSORS
คาร์ลเมเยอร์

จุดที่สอดคล้องกันในมุมมองทั่วไปและแอปหลักและแอคชั่นส่วนใหญ่บริบทเพิ่มเติมเรียกว่า extra_context และบ่อยครั้งที่มันรวมอยู่ในอาร์กิวเมนต์ของมุมมอง
Soviut

"Django ให้การเข้าถึงค่าคงที่การตั้งค่าที่ใช้บ่อยและแน่นอนสำหรับเทมเพลตเช่นการตั้งค่า MEDIA_URL" ดูเหมือนจะไม่ทำงานใน Django 1.3 แม้ว่าฉันอาจใช้ผิด มีเอกสารสำหรับคุณสมบัตินี้ไหม?
SystemParadox

1
@asofyan ใช่เพิ่มสร้างตัวประมวลผลบริบทเทมเพลตที่กำหนดเองและเพิ่มใน TEMPLATE_CONTEXT_PROCESSORS ใน settings.py
เปาโล

14
อย่ามองที่django-settings-exportจะหลีกเลี่ยงความต้องการที่จะเขียนรหัสนี้ในทุกมุมมอง
qris

441

หากเป็นค่าที่คุณต้องการสำหรับทุกคำขอ & แม่แบบการใช้ตัวประมวลผลบริบทจะเหมาะสมกว่า

นี่คือวิธี:

  1. สร้างcontext_processors.pyไฟล์ในไดเรกทอรีแอปของคุณ สมมติว่าฉันต้องการมีADMIN_PREFIX_VALUEคุณค่าในทุกบริบท:

    from django.conf import settings # import the settings file
    
    def admin_media(request):
        # return the value you want as a dictionnary. you may add multiple values in there.
        return {'ADMIN_MEDIA_URL': settings.ADMIN_MEDIA_PREFIX}
  2. เพิ่มตัวประมวลผลบริบทของคุณไปยังไฟล์settings.py :

    TEMPLATES = [{
        # whatever comes before
        'OPTIONS': {
            'context_processors': [
                # whatever comes before
                "your_app.context_processors.admin_media",
            ],
        }
    }]
  3. ใช้RequestContextในมุมมองของคุณเพื่อเพิ่มตัวประมวลผลบริบทของคุณในแม่แบบของคุณ renderทางลัดไม่นี้โดยอัตโนมัติ:

    from django.shortcuts import render
    
    def my_view(request):
        return render(request, "index.html")
  4. และในที่สุดในเทมเพลตของคุณ:

    ...
    <a href="{{ ADMIN_MEDIA_URL }}">path to admin media</a>
    ...

32
@MarkEssel ห่วงเหล่านี้ถูกสร้างขึ้นเพื่อให้ตัวแปรสามารถเข้าถึงได้ในทุกมุมมองที่คุณจะสร้างตราบเท่าที่ใช้ฟังก์ชัน RequestContext คุณสามารถเรียกตัวแปรการตั้งค่าได้ด้วยตนเองในทุกมุมมอง ฉันเลือกตัวประมวลผลบริบทที่ใช้ซ้ำได้ตลอดเวลาแทนที่จะคัดลอกและวาง ol ที่ดี
bchhun

5
ทำอย่างดีที่สุดเพื่อหลีกเลี่ยงการคัดลอก / วางทุกที่ที่เป็นไปได้ แต่ละแอปและทุกแอป (ภายในโครงการ) ต้องการ context_processor.py มีวิธีสร้างหนึ่ง context_processor สำหรับทั้งหมดหรือไม่
Mark Essel

10
@bchhun ฉันเพิ่งทดสอบ (Django 1.3): การแชร์โพรเซสเซอร์บริบทระหว่างแอพทำงานได้ดี :-) ฉันใส่context_process.pyถัดจากsettings.pyไฟล์ของฉันและเพิ่มลง"context_processors.admin_media"ในTEMPLATE_CONTEXT_PROCESSORSรายการของฉัน นอกจากนี้คุณอาจต้องการเพิ่มบันทึกย่อในคำตอบของคุณเกี่ยวกับความจริงที่ว่าค่าเริ่มต้นของ TEMPLATE_CONTEXT_PROCESSORS ไม่ว่างเปล่าดังนั้นหากรหัสใด ๆ ที่มีอยู่ใช้ค่าใด ๆ ที่กำหนดโดยตัวประมวลผลบริบทเริ่มต้นเหล่านั้นจะไม่ทำงานจนกว่าคุณจะเพิ่มกลับ ในรายการอย่างชัดเจน
MiniQuark

5
@ MarkEssel ไม่เจ็บปวดเลย - เขาแค่สะกดทุกอย่างออกมา มันเป็นเพียงสั้น ๆ 6 บรรทัด (ขั้นตอนที่ 1 และ 2) แม่แบบส่วนใหญ่จำเป็นต้องใช้ขั้นตอนที่ 3 และ 4 หรือสิ่งที่เทียบเท่ากัน
Rick Westera

2
ในฐานะของ Django 1.3 คุณสามารถใช้renderทางลัดเพื่อหลีกเลี่ยงการรวม RequestContext อย่างชัดเจน: docs.djangoproject.com/en/1.6/topics/http/shortcuts/#render
yndolok

269

ฉันพบวิธีที่ง่ายที่สุดในการเป็นแท็กเทมเพลตที่กำหนดเอง :

from django import template
from django.conf import settings

register = template.Library()

# settings value
@register.simple_tag
def settings_value(name):
    return getattr(settings, name, "")

การใช้งาน:

{% settings_value "LANGUAGE_CODE" %}

17
ฉันชอบที่จะเข้าถึงการตั้งค่าใด ๆ ในแม่แบบตามต้องการและนี่เป็นข้อเสนอที่สวยงาม นี่เป็นคำตอบที่ดีกว่าคำตอบอื่น ๆ หากคุณมักจะใช้การตั้งค่าต่าง ๆ ในแม่แบบของคุณ: 1) คำตอบที่ยอมรับไม่สามารถใช้ร่วมกันได้ 2) ด้วยโซลูชันตัวประมวลผลบริบทเทมเพลตที่ได้รับการโหวตมากเกินไปคุณจะต้องระบุการตั้งค่าส่วนบุคคล (หรือทั้งหมด) และมันจะทำงานสำหรับคำขอเดียวทุกครั้งที่ทำให้แม่แบบไม่มีประสิทธิภาพ! 3) มันง่ายกว่าแท็กที่ซับซ้อนกว่าด้านบน
Ben Roberts

16
@BenRoberts ฉันยอมรับว่านี่เป็นทางออกที่หรูหรา ... แต่สำหรับโครงการขนาดเล็กที่มีผู้พัฒนารายเดียวที่ทำทุกอย่าง ถ้าคุณมีแยกต่างหากคน / ทีมสำหรับการออกแบบและการพัฒนาแล้วการแก้ปัญหานี้น่าจะเป็นที่เลวร้ายที่สุด สิ่งที่จะหยุดนักออกแบบจากการใช้แท็กนี้ในลักษณะที่{% settings_value "DATABASES" %}ไม่เหมาะสม: กรณีใช้นี้ควรทำให้ชัดเจนว่าทำไมการตั้งค่าไม่พร้อมใช้งานในเทมเพลตเพื่อเริ่มต้น
mkoistinen

23
"เราทุกคนยินยอมผู้ใหญ่ที่นี่"
frnhr

11
ให้อภัยฉันเพราะเป็นมือใหม่ คุณใส่รหัสนี้ที่ไหน Views.py? หรือไฟล์ใหม่?
Noel Llevares

13
เพื่อให้ชัดเจนสำหรับคนอื่นคุณต้อง: 1) สร้างtemplatetagsโฟลเดอร์ภายในแอปของคุณด้วย__init__.pyไฟล์เปล่าและรหัสนี้เหมือนกับsettings.pyในโฟลเดอร์นั้น 2) ในแม่แบบของคุณคุณเพิ่ม{% load settings %}แล้วใช้แท็กใหม่ของคุณ!
damio

95

ตรวจสอบdjango-settings-export(ข้อจำกัดความรับผิดชอบ: ฉันเป็นผู้เขียนโครงการนี้)

ตัวอย่างเช่น...

$ pip install django-settings-export

settings.py

TEMPLATES = [
    {
        'OPTIONS': {
            'context_processors': [
                'django_settings_export.settings_export',
            ],
        },
    },
]

MY_CHEESE = 'Camembert';

SETTINGS_EXPORT = [
    'MY_CHEESE',
]

template.html

<script>var MY_CHEESE = '{{ settings.MY_CHEESE }}';</script>

1
และโปรดทราบว่าในมุมมองของคุณคุณจำเป็นต้องใช้renderและไม่render_to_response
Everett Toews

ฉันมีความต้องการที่คล้ายกันในการอ่านค่าจากการตั้งค่าในแม่แบบ แต่ฉันได้รับข้อผิดพลาด 500 เมื่อฉันเพิ่ม 'django_settings_export.settings_export' ในการตั้งค่า file.Can คุณแนะนำสิ่งที่ฉันทำผิดที่นี่
Piyush Sahu

3
มันคือ 2019 และฉันใช้มันในโครงการของฉัน ขอบคุณ!
sivabudh

1
ฉันเห็นด้วยกับ @sivabudh นี่เป็นทางออกที่ดีที่สุดสำหรับฉันเพราะ 1. เป็นแบบรวมศูนย์ซึ่งหมายความว่าฉันไม่ต้องการโฟลเดอร์และไฟล์เพิ่มเติม 2. ฉันสามารถเห็นเนมสเปซการตั้งค่าในแม่แบบของฉันซึ่งเป็นประโยชน์อย่างมากในการรับการอ้างอิงของแอปพลิเคชัน
ywiyogo

46

อีกวิธีในการทำเช่นนี้คือการสร้างแท็กแม่แบบที่กำหนดเองซึ่งสามารถให้คุณเก็บค่าจากการตั้งค่า

@register.tag
def value_from_settings(parser, token):
    try:
        # split_contents() knows not to split quoted strings.
        tag_name, var = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents.split()[0]
    return ValueFromSettings(var)

class ValueFromSettings(template.Node):
    def __init__(self, var):
        self.arg = template.Variable(var)
    def render(self, context):        
        return settings.__getattr__(str(self.arg))

จากนั้นคุณสามารถใช้:

{% value_from_settings "FQDN" %}

เพื่อพิมพ์บนหน้าใดก็ได้โดยไม่ต้องผ่านห่วงตัวประมวลผลบริบท


6
ฉันคิดว่านี่เป็นทางออกที่ยอดเยี่ยมที่สุดเพราะทำงานเป็น dropin โดยไม่ต้องเปลี่ยนรหัส
บินแกะ

1
คุณสามารถปล่อยให้แอปพลิเคชั่นที่เหลือไม่เปลี่ยนแปลง: คุณเพิ่มแท็กหนึ่งแท็กและใช้แทนการเพิ่มตัวประมวลผลบริบท (ซึ่งหมายความว่าคุณต้องแก้ไขแอปพลิเคชันของคุณในหลาย ๆ ที่)
Flying แกะ

2
@ Mark - ใน produi / src / produi / template_utils / templatetags / custom_template_filters.py template_utils อ้างอิงจาก settings.py INSTALLED_APPS - ยังเห็นdocs.djangoproject.com/en/dev/howto/custom-template-tags
fadedbee

ชื่นชมความช่วยเหลือคริสเพิ่มแอพ mutil ด้วยไดเรกทอรีย่อย templatetags รวมถึง custom_template_filters ยังคงได้รับข้อผิดพลาดใน homepage.html "แท็กบล็อกไม่ถูกต้อง: 'value_from_settings', คาดว่า 'endblock' หรือ 'endblock banner'"
Mark Essel

ฉันคิดว่าสิ่งนี้ขัดกับ "ชัดเจนดีกว่าโดยนัย" โดยใช้เวอร์ชัน decorator บริบทที่คุณเลือกว่าจะเปิดเผยการตั้งค่าแบบใด
sjh

29

ฉันชอบวิธีแก้ปัญหาของ Berislav เพราะในเว็บไซต์ธรรมดา ๆ มันสะอาดและมีประสิทธิภาพ สิ่งที่ฉันไม่ชอบคือการเปิดเผยการตั้งค่าทั้งหมดยังคงจำใจ ดังนั้นสิ่งที่ฉันทำคือ:

from django import template
from django.conf import settings

register = template.Library()

ALLOWABLE_VALUES = ("CONSTANT_NAME_1", "CONSTANT_NAME_2",)

# settings value
@register.simple_tag
def settings_value(name):
    if name in ALLOWABLE_VALUES:
        return getattr(settings, name, '')
    return ''

การใช้งาน:

{% settings_value "CONSTANT_NAME_1" %}

สิ่งนี้จะปกป้องค่าคงที่ใด ๆ ที่คุณไม่ได้ตั้งชื่อไม่ให้ใช้ในเทมเพลตและถ้าคุณต้องการที่จะได้รับแฟนซีคุณสามารถตั้งค่า tuple ในการตั้งค่าและสร้างแท็กเทมเพลตมากกว่าหนึ่งแท็กสำหรับหน้าแอพหรือพื้นที่ต่างๆ รวม tuple โลคัลกับ tuple การตั้งค่าตามต้องการจากนั้นทำรายการความเข้าใจเพื่อดูว่าค่านั้นยอมรับได้หรือไม่
ฉันเห็นด้วยบนเว็บไซต์ที่ซับซ้อนนี่เป็นเรื่องง่ายนิดหน่อย แต่มีค่าที่ดีที่จะมีอยู่ในแม่แบบสากลและดูเหมือนว่าจะทำงานได้ดี ขอบคุณ Berislav สำหรับแนวคิดดั้งเดิม!


5
ทำไมไม่ง่ายif name in ALLOWABLE_VALUES: ...
frnhr

เพราะฉันคิดว่าฉันฉลาดและต้องการป้องกันไม่ให้สตริงย่อยเรียกการตั้งค่า var ;-) ผลตอบแทนที่ควรจะเป็น: return getattr (การตั้งค่า, is_allowable, '')
MontyThreeCard

5
เพียงชี้แจงสำหรับทุกคนที่สงสัยว่า: 'val' in ('val_first', 'second_val',)จะFalseไม่มีปัญหา substring ที่นี่
frnhr

2
ฉันจะใช้สิ่งนี้ในifแถลงการณ์ได้อย่างไร? ฉันต้องการตรวจสอบDEBUGค่า
AJ

หากใครบางคนต้องการรุ่นที่มีgist.github.com/BrnoPCmaniak/632f56ddb907108b3d43fa862510dfca
Filip Dobrovolný

12

ฉันปรับปรุงคำตอบของ chrisdew (เพื่อสร้างแท็กของคุณเอง) เล็กน้อย

ขั้นแรกสร้างไฟล์yourapp/templatetags/value_from_settings.pyที่คุณกำหนดแท็กใหม่ของคุณเองvalue_from_settings:

from django.template import TemplateSyntaxError, Variable, Node, Variable, Library
from yourapp import settings

register = Library()
# I found some tricks in URLNode and url from defaulttags.py:
# https://code.djangoproject.com/browser/django/trunk/django/template/defaulttags.py
@register.tag
def value_from_settings(parser, token):
  bits = token.split_contents()
  if len(bits) < 2:
    raise TemplateSyntaxError("'%s' takes at least one " \
      "argument (settings constant to retrieve)" % bits[0])
  settingsvar = bits[1]
  settingsvar = settingsvar[1:-1] if settingsvar[0] == '"' else settingsvar
  asvar = None
  bits = bits[2:]
  if len(bits) >= 2 and bits[-2] == 'as':
    asvar = bits[-1]
    bits = bits[:-2]
  if len(bits):
    raise TemplateSyntaxError("'value_from_settings' didn't recognise " \
      "the arguments '%s'" % ", ".join(bits))
  return ValueFromSettings(settingsvar, asvar)

class ValueFromSettings(Node):
  def __init__(self, settingsvar, asvar):
    self.arg = Variable(settingsvar)
    self.asvar = asvar
  def render(self, context):
    ret_val = getattr(settings,str(self.arg))
    if self.asvar:
      context[self.asvar] = ret_val
      return ''
    else:
      return ret_val

คุณสามารถใช้แท็กนี้ในแม่แบบของคุณผ่าน:

{% load value_from_settings %}
[...]
{% value_from_settings "FQDN" %}

หรือผ่าน

{% load value_from_settings %}
[...]
{% value_from_settings "FQDN" as my_fqdn %}

ข้อดีของas ...สัญกรณ์คือมันทำให้ง่ายต่อการใช้งานในblocktransบล็อกผ่านทาง{{my_fqdn}}วิ


12

การเพิ่มคำตอบพร้อมคำแนะนำที่สมบูรณ์สำหรับการสร้างเทมเพลตแท็กแบบกำหนดเองที่แก้ปัญหานี้ด้วย Django 2.0+

ใน app โฟลเดอร์ของคุณสร้างโฟลเดอร์ที่เรียกว่าtemplatetags ในนั้นสร้าง__init__.pyและcustom_tags.py :

โครงสร้างโฟลเดอร์แท็กที่กำหนดเอง

ในcustom_tags.pyสร้างฟังก์ชั่นแท็กที่กำหนดเองที่ให้การเข้าถึงกุญแจโดยพลการในการตั้งค่าคงที่:

from django import template
from django.conf import settings

register = template.Library()

@register.simple_tag
def get_setting(name):
    return getattr(settings, name, "")

เพื่อทำความเข้าใจรหัสนี้ฉันแนะนำให้อ่านส่วนบนแท็กง่าย ๆใน Django docs

จากนั้นคุณต้องทำให้ Django รับรู้ถึงแท็กที่กำหนดเองนี้ (และเพิ่มเติม) โดยการโหลดไฟล์นี้ในเทมเพลตที่คุณจะใช้ เช่นเดียวกับที่คุณต้องโหลดแท็กแบบคงที่:

{% load custom_tags %}

เมื่อโหลดแล้วสามารถใช้งานได้เหมือนแท็กอื่น ๆ เพียงระบุการตั้งค่าเฉพาะที่คุณต้องการคืน ดังนั้นหากคุณมีตัวแปร BUILD_VERSION ในการตั้งค่าของคุณ:

{% get_setting "BUILD_VERSION" %}

โซลูชันนี้จะไม่ทำงานกับอาร์เรย์ แต่ถ้าคุณต้องการให้คุณใส่ตรรกะลงในแม่แบบของคุณ

หมายเหตุ: โซลูชันที่สะอาดและปลอดภัยยิ่งขึ้นอาจเป็นตัวประมวลผลบริบทที่กำหนดเองซึ่งคุณเพิ่มการตั้งค่าที่คุณต้องการให้กับบริบทที่มีให้กับเทมเพลตทั้งหมด วิธีนี้ช่วยลดความเสี่ยงในการแสดงผลการตั้งค่าที่ละเอียดอ่อนในแม่แบบโดยไม่ได้ตั้งใจ


9

เพิ่มรหัสนี้ไปยังไฟล์ชื่อcontext_processors.py:

from django.conf import settings as django_settings


def settings(request):
    return {
        'settings': django_settings,
    }

และแล้วในไฟล์ตั้งค่าของคุณรวมถึงเส้นทางเช่น'speedy.core.base.context_processors.settings'(มีชื่อของคุณแอปและเส้นทาง) ในการตั้งค่าใน'context_processors'TEMPLATES

(คุณสามารถดูตัวอย่างการตั้งค่า / base.pyและcontext_processors.py )

จากนั้นคุณสามารถใช้การตั้งค่าเฉพาะในรหัสแม่แบบใดก็ได้ ตัวอย่างเช่น:

{% if settings.SITE_ID == settings.SPEEDY_MATCH_SITE_ID %}

ปรับปรุง:SECRET_KEYรหัสข้างตีแผ่การตั้งค่าทั้งหมดเพื่อแม่รวมทั้งข้อมูลที่สำคัญเช่นคุณ แฮกเกอร์อาจใช้คุณสมบัตินี้ในการแสดงข้อมูลดังกล่าวในเทมเพลต หากคุณต้องการแสดงเฉพาะการตั้งค่าเทมเพลตให้ใช้รหัสนี้แทน:

def settings(request):
    settings_in_templates = {}
    for attr in ["SITE_ID", ...]: # Write here the settings you want to expose to the templates.
        if (hasattr(django_settings, attr)):
            settings_in_templates[attr] = getattr(django_settings, attr)
    return {
        'settings': settings_in_templates,
    }

1
ฉันพบปัญหานี้เมื่อวานนี้พบโพสต์นี้จากนั้นอีก 2 คนและโพสต์บล็อกและรู้สึกว่าทุกคนมีความซับซ้อนมากเกินไป (น่าเสียดายที่ฉันไม่ได้ทำให้เรื่องนี้น่าผิดหวังมาก) ดังนั้นฉันจึงลงเอยด้วยตัวเองซึ่งก็คือทางออกนี้ ฉันเพิ่งกลับมาเพราะมันเป็นการบั่นทอนฉันว่ามีคนแนะนำปลั๊กอินและรหัสทั้งหมดเมื่อ ^^^ ฟังก์ชั่น 3 บรรทัดและการเปลี่ยนแปลง 1 บรรทัดใน settings.py
DXM


SECRET_KEYอันที่จริงการแก้ปัญหาของฉันหมายความว่าการตั้งค่าทั้งหมดเพื่อแม่รวมทั้งข้อมูลที่สำคัญเช่น แฮกเกอร์อาจใช้คุณสมบัตินี้ในทางที่ผิดเพื่อแสดงข้อมูลดังกล่าวในเทมเพลต
แข่งขันที่รวดเร็ว

ฉันปรับปรุงคำตอบของฉัน
แข่งขันที่รวดเร็ว

ดี ... ดีตอนนี้เว็บไซต์ของฉันมีปัญหาเดียวกัน :) แต่ ... ฉันอาจจะหายไปบางสิ่งบางอย่างอย่างไรก็ตามเราแน่ใจว่ามีปัญหาหรือไม่ เทมเพลตนั้นเหมือนกับซอร์สโค้ดสำหรับเว็บไซต์ของคุณใช่ไหม พวกเขาจะถูกเก็บไว้ฝั่งเซิร์ฟเวอร์และไม่สามารถเข้าถึงได้โดยตรงจากส่วนหน้า หากแฮ็กเกอร์สามารถเปลี่ยนแม่แบบได้ ณ จุดนั้นพวกเขาสามารถเปลี่ยนไฟล์. py ได้
DXM

8

ตัวอย่างข้างต้นจาก bchhun นั้นดียกเว้นคุณต้องสร้างพจนานุกรมบริบทของคุณจาก settings.py อย่างชัดเจน ด้านล่างเป็นตัวอย่างที่ไม่ผ่านการทดสอบของวิธีที่คุณสามารถสร้างพจนานุกรมบริบทโดยอัตโนมัติจากแอตทริบิวต์ตัวพิมพ์ใหญ่ทั้งหมดของ settings.py (อีกครั้ง: "^ [A-Z0-9 _] + $")

ในตอนท้ายของ settings.py:

_context = {} 
local_context = locals()
for (k,v) in local_context.items():
    if re.search('^[A-Z0-9_]+$',k):
        _context[k] = str(v)

def settings_context(context):
    return _context

TEMPLATE_CONTEXT_PROCESSORS = (
...
'myproject.settings.settings_context',
...
)

8

หากมีคนพบคำถามนี้เหมือนฉันฉันจะโพสต์โซลูชันซึ่งใช้งานได้กับ Django 2.0:

แท็กนี้กำหนดค่า settings.py บางค่าให้กับตัวแปรของเทมเพลต:

การใช้งาน: {% get_settings_value template_var "SETTINGS_VAR" %}

app / templatetags / my_custom_tags.py:

from django import template
from django.conf import settings

register = template.Library()

class AssignNode(template.Node):
    def __init__(self, name, value):
        self.name = name
        self.value = value

    def render(self, context):
        context[self.name] = getattr(settings, self.value.resolve(context, True), "")
        return ''

@register.tag('get_settings_value')
def do_assign(parser, token):
    bits = token.split_contents()
    if len(bits) != 3:
        raise template.TemplateSyntaxError("'%s' tag takes two arguments" % bits[0])
    value = parser.compile_filter(bits[2])
    return AssignNode(bits[1], value)

แม่แบบของคุณ:

{% load my_custom_tags %}

# Set local template variable:
{% get_settings_value settings_debug "DEBUG" %}

# Output settings_debug variable:
{{ settings_debug }}

# Use variable in if statement:
{% if settings_debug %}
... do something ...
{% else %}
... do other stuff ...
{% endif %}

ดูเอกสารประกอบของ Django เกี่ยวกับวิธีสร้างแท็กเทมเพลตที่กำหนดเองได้ที่นี่: https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/


1
{% if settings_debug %}
user66081

ขอบคุณ @ user66081! เปลี่ยน{% if settings_debug == True %}เป็นข้อเสนอแนะของคุณ{% if settings_debug %}
NullIsNot0

7

หากใช้มุมมองแบบคลาส:

#
# in settings.py
#
YOUR_CUSTOM_SETTING = 'some value'

#
# in views.py
#
from django.conf import settings #for getting settings vars

class YourView(DetailView): #assuming DetailView; whatever though

    # ...

    def get_context_data(self, **kwargs):

        context = super(YourView, self).get_context_data(**kwargs)
        context['YOUR_CUSTOM_SETTING'] = settings.YOUR_CUSTOM_SETTING

        return context

#
# in your_template.html, reference the setting like any other context variable
#
{{ YOUR_CUSTOM_SETTING }}

3

ฉันพบสิ่งนี้เป็นวิธีที่ง่ายที่สุดสำหรับ Django 1.3:

  1. views.py

    from local_settings import BASE_URL
    
    def root(request):
        return render_to_response('hero.html', {'BASE_URL': BASE_URL})
  2. hero.html

    var BASE_URL = '{{ JS_BASE_URL }}';

1

ทั้ง IanSR และ bchhun แนะนำให้เอาชนะ TEMPLATE_CONTEXT_PROCESSORS ในการตั้งค่า โปรดทราบว่าการตั้งค่านี้มีค่าเริ่มต้นที่อาจทำให้เกิดสิ่งที่ไม่พึงประสงค์หากคุณแทนที่โดยไม่ต้องตั้งค่าเริ่มต้นใหม่ ค่าเริ่มต้นมีการเปลี่ยนแปลงใน Django เวอร์ชันล่าสุดด้วย

https://docs.djangoproject.com/en/1.3/ref/settings/#template-context-processors

TEMPLATE_CONTEXT_PROCESSORS เริ่มต้น:

TEMPLATE_CONTEXT_PROCESSORS = ("django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.static",
"django.contrib.messages.context_processors.messages")

1

หากเราต้องเปรียบเทียบบริบทกับแท็กเทมเพลตในตัวแปรเดียวการรู้ว่าตัวเลือกที่มีประสิทธิภาพมากขึ้นนั้นสามารถสร้างประโยชน์ได้ อย่างไรก็ตามคุณอาจจะดีกว่าที่จะจุ่มลงในการตั้งค่าเฉพาะจากแม่แบบที่ต้องการตัวแปรนั้น ในกรณีนั้นมันไม่มีเหตุผลที่จะส่งตัวแปรไปยังเทมเพลตทั้งหมด แต่ถ้าคุณกำลังส่งตัวแปรไปยังเทมเพลตทั่วไปเช่นเทมเพลต base.html แล้วมันก็ไม่สำคัญว่าเทมเพลต base.html นั้นจะถูกเรนเดอร์กับทุกคำขอหรือไม่ดังนั้นคุณสามารถใช้วิธีการใดก็ได้

หากคุณตัดสินใจที่จะใช้ตัวเลือกเทมเพลตแท็กให้ใช้รหัสต่อไปนี้เพื่อให้คุณสามารถส่งค่าเริ่มต้นในกรณีที่ตัวแปรในคำถามไม่ได้กำหนดไว้

ตัวอย่าง: get_from_settings my_variable เป็น my_context_value

ตัวอย่าง: get_from_settings my_variable my_default เป็น my_context_value

class SettingsAttrNode(Node):
    def __init__(self, variable, default, as_value):
        self.variable = getattr(settings, variable, default)
        self.cxtname = as_value

    def render(self, context):
        context[self.cxtname] = self.variable
        return ''


def get_from_setting(parser, token):
    as_value = variable = default = ''
    bits = token.contents.split()
    if len(bits) == 4 and bits[2] == 'as':
        variable = bits[1]
        as_value = bits[3]
    elif len(bits) == 5 and bits[3] == 'as':
        variable     = bits[1]
        default  = bits[2]
        as_value = bits[4]
    else:
        raise TemplateSyntaxError, "usage: get_from_settings variable default as value " \
                "OR: get_from_settings variable as value"

    return SettingsAttrNode(variable=variable, default=default, as_value=as_value)

get_from_setting = register.tag(get_from_setting)

หรือคุณสามารถใช้SITE_EXTRA_CONTEXT_DICTในfinalwareเพื่อทำเพื่อคุณ
un33k
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.