开发者

Cannot get MEDIA_URL from Django widget's template

开发者 https://www.devze.com 2022-12-27 09:45 出处:网络
I am a new Djangoer, and figuring out how to build custom widget, my problem is cannot get the MEDIA_URL in my widget\'s template, while the form use MySelectWidget able to get the MEDIA_URL itself.

I am a new Djangoer, and figuring out how to build custom widget, my problem is cannot get the MEDIA_URL in my widget's template, while the form use MySelectWidget able to get the MEDIA_URL itself.

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

^ cannot load the {{ MEDIA_URL}} to this widget's template, and therefore I can't load the .gif image properly. :(

#
#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

开发者_StackOverflow#
#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 %}

Please let me know how can I load the widget's image properly. Thank you so much for all responses.


Context processors only get applied when you use a RequestContext.

Your render method should be something like:

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

And, as was mentioned by @czarchaic, make sure the media context processor is in TEMPLATE_CONTEXT_PROCESSORS (it should be by default).

Docs link.


Actually the correct way to do this is using Widget Media.

When defining your widget, you should define a Media inner class in which you should include a CSS file in order to style your widget. In this case make the <a> tag not to display text and have a plus sign background image.

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

If you really need to include the MEDIA_URL inside your rendered widget, I'd recommmend to import it directly from django.conf.settings and include settings.MEDIA_URL in your rendering context.

from django.conf import settings

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


Make sure the context processor is being loaded in settings.py

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

It is loaded by default if you don't specify TEMPLATE_CONTEXT_PROCESSORS, but if specified, the above processor must also be included.

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


I think we can do in this way, to pass the RequestContext, in order to access the MEDIA_URL without making another variable, and passing other variables at the 2nd parameter of the render_to_string method.

If we use:

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

The {{ field }} in the widget's template is empty and not able to access.

Here is the block which can access the MEDIA_URL as well as the {{ field }}. However, I agree using the inner Media class for complex javascript and CSS setting. However, for a simple image src path, I think this will do.

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

Please correct me if this is not the good way of doing it. Thanks for all participants of this thread.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号