Django admin ManyToManyField add button and list display - python

Let's say I have models:
from filer.fields.image import FilerImageField()
class Image(models.Model):
name = models.CharField(max_length=128)
image = FilerImageField()
class City(models.Model):
name = models.CharField(max_length=128)
images = models.ManyToManyField(Image, blank=True)
admin.py:
class ImageAdmin(admin.ModelAdmin):
def thumb(self, obj):
return '<img src=%s />' %obj.image.icons['64']
thumb.short_description = 'Preview'
thumb.allow_tags = True
list_display = ('image', 'name', 'thumb', )
class CityAdmin(models.ModelAdmin):
filter_horizontal = ('images', )
admin.site.register(Image, ImageAdmin)
admin.site.register(City, CityAdmin)
Questions:
1. How to add "+" button in CityAdmin above m2m widget? Currently what i have:
2. Is it possible in CityAdmin m2m widget have some list display where I can see image thumbnail? Ideally like in ImageAdmin:
What I have tried:
In Image model __unicode__ function return '<img src=%s />' %self.image.icons['64'], but then in admin it just displays raw text.

Related

Django admin drop down with very long description/text

just like the pic in admin panel when creating some post:
that basically one of dropdown menu options, it is so long, is there any idea on how i can change it to be multi-line? or maybe change the drop down menu to a "select table", the admin in this case need to read the description, so it is unwise for it to be formatted like that.
I have a code example:
models.py
class CreatePost(models.Model):
subject = models.CharField(max_length=99)
desc = models.TextField(max_length=9000)
isSolved = models.BooleanField(default=False) # a button
user = models.ForeignKey(User, on_delete=models.CASCADE,related_name="user_post")
def __str__(self):
return format_html('SUBJECT : {} <br/> DESCRIPTION : {} <br/> Email : {} <br/> ',self.subject, self.desc, self.user.username)
# remember to show the name of ticket sender
class RespondToPost(models.Model):
ticket = models.ForeignKey(CreatePost,on_delete=models.CASCADE)
to = models.EmailField(max_length=320)
content = models.TextField()
def __str__(self):
return format_html('SUBJECT : {} <br/> DESCRIPTION : {} <br/> EMAIL : {} <br/> ',self.post.subject, self.post.desc, self.post.user.username)
admin.py
class CreatePostAdmin(admin.ModelAdmin):
list_display = ('id', '__str__')
class Meta:
model = models.CreatePost
class RespondToPostAdmin(admin.ModelAdmin):
list_display = ('id', '__str__', 'to', 'content')
class Meta:
model = models.RespondToPost
any idea?
You can add a custom field to list_display and change its content however you like:
from django.utils.text import Truncator # for shortening a text
class CreatePostAdmin(admin.ModelAdmin):
list_display = ('id', 'get_truncated_str')
class Meta:
model = models.CreatePost
def get_truncated_str(self, obj):
# Change it however you want, shortening is just an example
return Truncator(str(obj)).words(10)

How to display an image inside Django Admin's detail view of a model?

I want to display an image inside a detail view of a model, when browsing through Django Admin. I have seen other posts about displaying images in the list view of all instances of a model in Django Admin. But I'm interested in seeing the image on the page where you can edit the data.
models.py
class Label(models.Model):
label = models.TextField()
fragment = models.ForeignKey('Fragment', models.DO_NOTHING, null=True)
in_english = models.BooleanField(default=True)
validated = models.BooleanField(default=False)
def __str__(self):
return str(self.fragment)
admin.py
#admin.register(Label)
class LabelsAdmin(admin.ModelAdmin):
fields = ("label", "in_english", "validated", )
# What I tried. This is not working even after adding 'image' to the fields. I get an error.
# def image(self, obj):
# return format_html('<img src="{0}" />'.format(f"/static/fragments/{obj}.png"))
you create a method like display_image.
def display_image(self, obj):
# get image url
image_url = '<your_image_url>'
if image_url is not None:
return format_html('<img src="{}">', image_url)
return None
Add 'display_image' in fields list
fields = ("label", "in_english", "validated", 'display_image')
then make this field as a readonly
readonly_fields = ['display_image']

Django , how to show 'secondary property' of parent in TabularInline

I try to do tabular inline admin.
In the child tab, if we include a ForeignKey field, it will show the str property of that foreign model.
But how to also show another property of that foreign model?
Here is my models.py
class RawMaterial(models.Model):
name = models.CharField(max_length=15)
ubuy = models.CharField(max_length=5)
usell = models.CharField(max_length=5)
uconv = models.DecimalField(max_digits = 5,decimal_places=2)
def __str__(self):
return self.name
class Coctail(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class Ingredient(models.Model):
coctail = models.ForeignKey(Coctail,
related_name='ingredient',
on_delete=models.CASCADE)
rawmaterial = models.ForeignKey(RawMaterial,
related_name='ingredient',
on_delete=models.CASCADE)
qty = models.DecimalField(max_digits = 5,decimal_places=2)
def __str__(self):
return self.rawmaterial
def rawusell(self):
return self.rawmaterial.usell
rawusell.short_description = 'UOM'
Here is my admin.py
from django.contrib import admin
# Register your models here.
from .models import *
admin.site.register(RawMaterial)
class IngredientInline(admin.TabularInline):
model = Ingredient
list_display = ('rawmaterial', 'qty', 'rawusell')
class CoctailAdmin(admin.ModelAdmin):
inlines = [IngredientInline]
admin.site.register(Coctail, CoctailAdmin)
and here what I got
My question is : How to show rawmaterial.usell in Ingredient tab?
Sincerely
-bino-
You can show the rawmaterial.usell field in the ingredient tab but it will not be editable. Since, any field can only be editable if they are a field of that model (Without using any custom form and logic).
So, if you want rawmaterial.usell to be editable, you will have to make a rawmaterial admin
You can show the rawmaterial.usell in IngredientInline by doing this.
class IngredientInline(admin.TabularInline):
model = Ingredient
readonly_fields = ('rawusell', )
list_display = ('rawmaterial', 'qty', 'rawusell')
def rawusell(self, obj):
return obj.rawmaterial.usell
This will start showing usell in the inline admin.

Displaying image from ForeignKey in Admin Panel in Django

I have in project two classes - Photo and Prescription inside models.py file which are related each other with foreign key. Here is part of the code:
class Photo(models.Model):
name = models.CharField(max_length=100,null=False)
photo = models.ImageField(upload_to="photos/",null=True)
def photo_tag(self):
return '<img src="/media/{0}">'.format(self.photo)
photo_tag.short_description = 'Photo of prescription'
photo_tag.allow_tags = True
class Prescription(models.Model):
description = models.CharField(max_length=100,null=True)
photo = models.ForeignKey(Photo, related_name='related_photo',null=True)
def __str__(self):
return self.description
And my Admin.py
class PhotoAdmin(admin.ModelAdmin):
list_display = ('name', 'photo_tag')
fields = ('name','photo','photo_tag')
readonly_fields = ('photo_tag',)
admin.site.register(Photo,PhotoAdmin)
class PrescriptionAdmin(admin.ModelAdmin):
list_display = ('get_photo')
fields = ('photo','description')
model = Prescription
def get_photo(self, obj):
return obj.photo.photo_tag
get_photo.short_description = 'Photo of prescription'
admin.site.register(Prescription,PrescriptionAdmin)
Question is, when I open prescriptions list instead of photo in the Photo of prescription field shows following message.
<bound method Photo.photo_tag of <Photo: Photo object>>
How real photo could be described there?
If you are going to render the image in html (which I guess you are), could you not then use ginger to display the description in a similar way to this?
<img src="{{photo.url}" title="{{photo.short_description}}" alt="{{photo.short_description}}">
Note that I included the alt for internet explorer which seems to use that instead of title.
There are few wrong issues with your approach. Your photo_tag method should be a property method, or eventually cached_property method. For displaying safely HTML code you should use the method format_html provided by Django.
Here is how I'd refactor your code:
models.py
from django.db import models
from django.utils.html import format_html
from django.utils.functional import cached_property
class Photo(models.Model):
name = models.CharField(max_length=100, null=False)
photo = models.ImageField(upload_to="photos/", null=True)
# better use blank=True instead of null=True for ImageField
#cached_property
def photo_tag(self):
if self.photo:
return format_html(
'<img src="{img}">',
img=self.photo.url
)
return None # or better return '' if you use blank=True
photo_tag.short_description = 'Photo of prescription'
class Prescription(models.Model):
description = models.CharField(max_length=100, null=True)
photo = models.ForeignKey(Photo, related_name='related_photo', null=True)
def __str__(self):
return self.description
Now you can use photo_tag as a property of Photo and bind the HTML safe in your admin.
Thanks anybody who tried to help. I figured out another solution with help of #Klaus who answered first and I am pretty sure that there is maybe much more better solutions also. Here are how I changed my code
Models.py
from django.utils.safestring import mark_safe
class Photo(models.Model):
name = models.CharField(max_length=100,null=False)
photo = models.ImageField(upload_to="photos/",null=True)
def photo_tag(self):
return mark_safe('<img src="/media/{0}">'.format(self.photo))
photo_tag.short_description = 'Photo of prescription'
photo_tag.allow_tags = True
class Prescription(models.Model):
description = models.CharField(max_length=100,null=True)
photo = models.ForeignKey(Photo, related_name='related_photo',null=True)
def __str__(self):
return self.description
Admin.py
class PhotoAdmin(admin.ModelAdmin):
list_display = ('name', 'photo_tag')
fields = ('name','photo','photo_tag')
readonly_fields = ('photo_tag',)
admin.site.register(Photo,PhotoAdmin)
class PrescriptionAdmin(admin.ModelAdmin):
list_display = ('get_photo')
fields = ('photo','description')
model = Prescription
def get_photo(self, obj):
return obj.photo.photo_tag()
get_photo.short_description = 'Photo of prescription'
admin.site.register(Prescription,PrescriptionAdmin)

Django Admin not Show Image from Imagefield

I want to show image like this Django admin listview Customize Column Name.
I've checked Django Admin Show Image from Imagefield, Django - Display ImageField, Django - How can I display a photo saved in ImageField?.
This is my models.py and admin.py.
#models.py
class Movie(models.Model):
id = models.IntegerField(primary_key=True)
master_id = models.IntegerField()
url = models.CharField(max_length=100)
cover = models.CharField(max_length=100)
tittle = models.CharField(max_length=50)
duration = models.CharField(max_length=10)
click = models.IntegerField()
platform_time = models.DateTimeField()
platform_type = models.IntegerField()
entry_date = models.DateTimeField()
enable = models.IntegerField()
def image_tag(self):
return u'<img src="%s" />' % self.cover
image_tag.short_description = 'Image'
image_tag.allow_tags = True
class Meta:
managed = False
db_table = 'movie'
#admin.py
class MovieAdmin(admin.ModelAdmin):
list_display = ('id', 'master_id', 'url', 'cover', 'tittle', 'duration', 'click', 'platform_time', 'platform_type', 'entry_date', 'enable')
search_fields = ('id', 'tittle',)
list_filter = ( 'enable', )
readonly_fields = ( 'image_tag', )
Now, this is a part of my interface, there is no image_tag field. Further more, If I modify cover field to image_tag, the cover field is still not image visible.
You have to use an ImageField for cover instead of CharField and also change the image_tag return line:
cover = models.ImageField(upload_to = "images") #use the directory you want here
def image_tag(self):
return u'<img src="%s" />' % self.cover.url
Also you have to add the image_tag field to list_display.
And make sure that django can find the upload_to directory.
You have no 'image_tag' column (which contains <img...>) in list_view.
I wrote valid answer about images in django-admin listview for django 2.0.6.
Here is link on my answer:
Django: Display image in admin interface
I hope it will help someone.

Categories

Resources