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 1. Am I just making some kind of mistake when I try to send back the string from the model? 2. Am I doing something that is unexpected? It seems like this should work. 3. 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 = 0 formfield_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+unsubscr...@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/e4d7ef94-181c-4f09-8471-e038455793e6%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.