无法从Django小部件的模板中获取MEDIA_URL

时间:2010-04-16 22:21:41

标签: django forms templates media

我是一个新的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 %}

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

4 个答案:

答案 0 :(得分:2)

仅在使用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

答案 1 :(得分:1)

确保在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

答案 2 :(得分:1)

实际上,正确的方法是使用Widget Media

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

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,
      ...
    })

答案 3 :(得分:0)

我认为我们可以通过这种方式传递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

如果这不是一个好方法,请纠正我。感谢此主题的所有参与者。