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:
>
> 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/9ab8d2ea-cf84-4e4f-ae21-507d70ed6e00%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to