I found that the "correct" way to address this issue is to use raw_id_fields.
On Tuesday, 16 June 2015 19:46:51 UTC-7, Dennis Marwood wrote:
-- On Tuesday, 16 June 2015 19:46:51 UTC-7, Dennis Marwood wrote:
Hello,
I want to display images in my manyTomany so that a user can choose what images would be included inside of a "BlogWidgetCarousel". The issue I am running into is that the render function for the widget returns html via the "format_html" and the variable has lost its "safe" setting at that point.
In my model I return the choice_label with "mark_safe" but somewhere along the way the string is altered and it must be losing that quality. (For the example I just changed it to a <b> tag)
I have found the render method and confirmed that I can set the string back to a safe state and it works fine.
My questions
- Am I just making some kind of mistake when I try to send back the string from the model?
- Am I doing something that is unexpected? It seems like this should work.
- Would you create a custom widget to solve this issue, if not what would you use?
#models.py
class BlogWidgetCarousel(models.Model ):
entry = models.TextField()
blog = models.ForeignKey(Blog, blank=True, null=True)
position = models.PositiveSmallIntegerField ("Position")
images = models.ManyToManyField("Image")
class Meta:
ordering = ('position', )
def __str__(self):
return str(self.position)
def save(self, *args, **kwargs):
self.entry = "<b><i>TODO: create image slider</i></b>"
super(BlogWidgetCarousel, self).save(*args, **kwargs)
def display(self):
return self.entry
class Image(models.Model):
title = models.CharField(max_length=60, blank=False, null=False)
image = models.ImageField(upload_to="images/" )
def thumb(self):
return '<a href="{0}"><img src="{0}"></a>'.\
format(MEDIA_URL + str(self.image))
def __str__(self):
return mark_safe(u'<b>bold</b>')
__str__.allow_tags = True#admin.py
class BlogWidgetCarouselInline(admin. StackedInline): #, SortableInline):
model = BlogWidgetCarousel
extra = 0formfield_overrides = {
models.ManyToManyField: {'widget': CheckboxSelectMultiple},
}
fieldsets = (
("Create Carousel:", {
'fields': (("position"), 'images',)
}),
("Result:", {
'fields': ('thumb', 'display_as',)
}),
)
readonly_fields = ('display_as', 'thumb',)
def display_as(self, instance):
return instance.display()
display_as.allow_tags = True
def thumb(self, instance):
x = ""
for i in instance.images.all():
x += i.thumb()
return x
thumb.allow_tags = True
class EntryAdmin(admin.ModelAdmin):
list_display = ("title", "created")
prepopulated_fields = {"slug": ("title",)}
inlines = [
BlogWidgetTextInline, BlogWidgetCarouselInline,
]#dist-packages/django/forms/widgets
#...
@html_safe
@python_2_unicode_compatible
class ChoiceInput(SubWidget):
"""
An object used by ChoiceFieldRenderer that represents a single
<input type='$input_type'>.
"""
input_type = None # Subclasses must define this
def __init__(self, name, value, attrs, choice, index):
self.name = name
self.value = value
self.attrs = attrs
self.choice_value = force_text(choice[0])
self.choice_label = force_text(choice[1])
self.index = index
if 'id' in self.attrs:
self.attrs['id'] += "_%d" % self.index
def __str__(self):
return self.render()
def render(self, name=None, value=None, attrs=None, choices=()):
if self.id_for_label:
label_for = format_html(' for="{}"', self.id_for_label)
else:
label_for = ''
attrs = dict(self.attrs, **attrs) if attrs else self.attrs
#print self.choice_label <---- Prints"<b>bold</b>"as expected.
return format_html('<label{}>{} {}</label>', label_for, self.tag(attrs), self.choice_label) # choice_label is escaped by format_html
#return format_html('<label{}>{} {}</label>', label_for, self.tag(attrs), mark_safe(self.choice_label)) <---Works
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/9ab8d2ea-cf84-4e4f-ae21-507d70ed6e00%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
No comments:
Post a Comment