【问题标题】:Cannot get MEDIA_URL from Django widget's template无法从 Django 小部件的模板中获取 MEDIA_URL
【发布时间】:2011-02-09 00:41:18
【问题描述】:

我是一个新的 Djangoer,正在弄清楚如何构建自定义小部件,我的问题是无法在我的小部件模板中获取 MEDIA_URL,而表单使用 MySelectWidget 能够获取 MEDIA_URL 本身。

#
#plus_sign.html
#
<a href="" class="" id="id_{{ field }}">
    <img src="{{ MEDIA_URL }}images/plus_sign.gif" width="10" height="10" alt="Add"/>
</a>

^ 无法将 {{ MEDIA_URL}} 加载到此小部件的模板中,因此我无法正确加载 .gif 图像。 :(

#
#custom_widgets.py
#
from django import forms

class MySelectMultiple(forms.SelectMultiple):

    def render(self, name, *args, **kwargs):
        html = super(MySelectMultiple, self).render(name, *args, **kwargs)
        plus = render_to_string("plus_sign.html", {'field': name})
        return html+plus

#
#forms.py
#
from django import forms
from myapp.custom_widgets.py import MySelectMultiple

class MyForm(forms.ModelForm):
contacts = forms.ModelMultipleChoiceField(Contact.objects, required=False, widget=MySelectMultiple)

#
#views.py
#

def AddContacts(request):
    if request.method == 'POST':
        form = MyForm(request.POST)

        if form.is_valid():
            cd = form.cleaned_data
            new = form.save()
            return HttpResponseRedirect('/addedContact/')
    else:
        form = MyForm()

    return render_to_response('shop/my_form.html', {'form': form}, context_instance=RequestContext(request))


#
#my_form.html
#
{% extends "base.html" %}

{% block content %}
   {{ form.contacts }}
{% endblock %}

请告诉我如何正确加载小部件的图像。非常感谢大家的回复。

【问题讨论】:

    标签: django forms templates media


    【解决方案1】:

    只有在您使用RequestContext 时才会应用上下文处理器。

    你的渲染方法应该是这样的:

    from django.template import RequestContext
    
    def render(self, name, *args, **kwargs):
        html = super(MySelectMultiple, self).render(name, *args, **kwargs)
        context = RequestContext({'field': name})
        plus = render_to_string("plus_sign.html", context)
        return html + plus
    

    并且,正如@czarchaic 所提到的,确保媒体上下文处理器位于TEMPLATE_CONTEXT_PROCESSORS 中(默认情况下应该是)。

    Docs link.

    【讨论】:

    • 这种方法存在问题,因为您需要以某种方式将请求发送到小部件,因为 RequestContext 将请求作为其第一个参数。
    • 非常感谢@Seth,我认为小部件会自动获取之前使用它的表单的 RequestContext,而无需显式使用 RequestContext 来扭曲传递回视图的变量。这行得通。非常感谢!
    • 但我现在似乎无法访问小部件模板中的 {{ field }}
    【解决方案2】:

    其实正确的做法是使用Widget Media

    在定义您的小部件时,您应该定义一个媒体内部类,您应该在其中包含一个 CSS 文件,以便为您的小部件设置样式。在这种情况下,使 标记不显示文本并具有加号背景图像。

    class MyWidget(TexInput):
      ...
      class Media:
        css = {
          'all': ('my_widget.css',)
        }
    

    如果您真的需要在渲染的小部件中包含 MEDIA_URL,我建议直接从 django.conf.settings 导入它并在渲染上下文中包含 settings.MEDIA_URL。

    from django.conf import settings
    
    class MyWidget(TextInput):
      ...
      def render(self):
        return render_to_string('my_widget.html', {
          'MEDIA_URL': settings.MEDIA_URL,
          ...
        })
    

    【讨论】:

    • 那不是说我们连图片源都必须使用CSS来指定图片路径位置吗?
    【解决方案3】:

    确保在 settings.py 中加载了上下文处理器

    TEMPLATE_CONTEXT_PROCESSORS=(
        ...other processors,
        "django.core.context_processors.media",
    )
    

    如果不指定TEMPLATE_CONTEXT_PROCESSORS,则默认加载,但如果指定,还必须包含上述处理器。

    http://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors

    【讨论】:

    • 您好 czarchaic,感谢您的回复。我在 settings.py 中添加了这个: TEMPLATE_CONTEXT_PROCESSORS = ( #...other processor, 'django.core.context_processors.media', ) 但仍然不起作用:(
    • 准确来说,如果我把 {{ MEDIA_URL}} 放在 my_form.html 中,它可以获取媒体 url,但小部件 DOESN"T
    【解决方案4】:

    我认为我们可以这样做,传递 RequestContext,以便访问 MEDIA_URL 而无需创建另一个变量,并在 render_to_string 方法的第二个参数处传递其他变量。

    如果我们使用:

    context = RequestContext({'field': name})
    

    小部件模板中的 {{ field }} 为空,无法访问。

    这是可以访问 MEDIA_URL 以及 {{ field }} 的块。 但是,我同意将内部 Media 类用于复杂的 javascript 和 CSS 设置。不过,对于一个简单的图片src路径,我觉得还是可以的。

    def render(self, name, *args, **kwargs):
            html = super(SelectMultipleWithModalDialog, self).render(name, *args, **kwargs)        
            **context = RequestContext({})
            popup_plus = render_to_string("widgets/modal_dialog_plus_sign.html", {'field': name}, context_instance=context)**        
            return html + popup_plus
    

    如果这不是做这件事的好方法,请纠正我。感谢本主题的所有参与者。

    【讨论】:

      猜你喜欢
      • 2011-11-11
      • 2010-12-21
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-04
      • 2017-02-27
      相关资源
      最近更新 更多