Can Django admin show the image after the model name? - django

I have a problem.
Can I add image after the Model name in the django admin?
The postion I want to add the picture.
I want to see the books image when I login admin page
I have no idea about it
maybe I can use verbose_name with inject html tag?
Can django do it? Or I should use others way to do it?

Basically, You could customize ModelAdmin.list_display in Django admin list view, for example:
Suppose you have a model MyModel with an image field named image
from django.utils.html import format_html
#admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
list_display = ('id', 'image_tag')
def image_tag(self, obj):
return format_html("<img src="{}" width=200 height=80/>'.format(obj.image.url))
image_tag.short_description = 'Image'

Related

Django admin filter on edit page

On a Django admin edit page, I would like to add a little search box to be able to filter a list of tags. The field tag is a many to many field.
Is there a special trick?
you can't add search field inside the box but you can search for the same field value at the top
add this to your admin.py file
#admin.py
from django.contrib import admin
from Your_app.models import Your_model
class example_class(admin.ModelAdmin):
search_fields = ['ManyToManyFiledname']
admin.site.register(Your_model,example_class)
I found the documentation on https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.autocomplete_fields
The code below adds a search box:
class TagAdmin(admin.ModelAdmin):
search_fields = ['name']
class CompanyAdmin(admin.ModelAdmin):
autocomplete_fields = ['tags']

Render a select box as radios buttons in Django Admin

I want to show select box options as raido buttons in Django Admin change model view. I don't want to write custom model forms. I'm looking for a way to render some select boxes as radio buttons while keeping auto generated model forms of the Django admin. I'm using django v 1.11.
Assuming my_field is the field, we want to be rendered as Radio Button
# admin.py
from django.contrib import admin
from django import forms
from .models import MyModel
class MyModelAdminForm(forms.ModelForm):
class Meta:
model = MyModel
exclude = ()
widgets = {'my_field': forms.RadioSelect}
class MyModelAdmin(admin.ModelAdmin):
form = MyModelAdminForm
admin.site.register(MyModel, MyModelAdmin)

Hiding a model field in Django admin 1.9

I have registered some models to display in the admin area, but I would like for some fields to be hidden.
As an example, I have a TeachingClasses model with a BooleanField named 'Status' that is set to True or False depending if the class is open or not. But that is set somewhere else in the app. There is no need to have that field displayed in the admin area when someone wants to create a new class to attend.
As such, is there a way to hide that field in the admin area?
I have tried adding this to the app admin.py file but it did nothing
from django.contrib import admin
class MyModelAdmin(admin.ModelAdmin):
class TeachingClasses:
exclude = ('Status',)
but it's not working?
Any clue if this is the right way?
My model:
class TeachingClasses(models.Model):
name = models.Charfield('Class Name',max_lenght=64)
[...]
status = models.BooleanField('Status',default=True)
What you did is not the correct syntax, you need:
class TeachingClassesAdmin(admin.ModelAdmin):
exclude = ('status',)
admin.site.register(TeachingClasses, TeachingClassesAdmin)
Django doc about how to use exclude.
In the admin.py:
class TeachingClassesAdmin(admin.ModelAdmin):
list_display = ('name',) # plus any other fields you'd like to display
admin.site.register(TeachingClasses, TeachingClassesAdmin)`

Django admin: ManyToManyField in list_editable?

In the Django admin, I would really like to be able to display an editable ManyToManyField in the list display.
It doesn't necessarily need to be the full ManyToManyField control - being able to save just one value would be good enough for the purposes of the list display (though the underlying values are many-to-many in nature).
My model looks like this:
class Item(models.Model):
name = models.CharField(max_length=500)
colour = models.ManyToManyField(Colour, related_name='primary_colour')
If I try this in admin.py:
class ItemAdmin(admin.ModelAdmin):
list_display = ('name', 'colour')
list_editable = ('colour')
Then I get this error:
'ItemAdmin.list_display[6]', 'colour' is a ManyToManyField which is not supported.
Is there any way at all that I can show an editable ManyToManyField for rapid editing in the list display?
I found this related question, which explains how to make the values visible in the list display, but not editable: ManyToManyField widget in a django admin change list?
Django by default won't allow to add ManyToManyField in list_editable in ModelAdmin. So we need to override model admin methods.
On looking your models you need to follow below steps to get the ManyToManyField editable in list display page.
In apps/forms.py you need to define which ManyToMany fields you need to make editable in list display page. As below,
from django import forms
from app.models import Item
class ItemChangeListForm(forms.ModelForm):
# here we only need to define the field we want to be editable
colour = forms.ModelMultipleChoiceField(queryset=Colour.objects.all(),
required=False)
In app/admin.py you need to override methods of model admin. As below,
from django.contrib import admin
from django.contrib.admin.views.main import ChangeList
from app.models import Item
from app.forms import ItemChangeListForm
class ItemChangeList(ChangeList):
def __init__(self, request, model, list_display,
list_display_links, list_filter, date_hierarchy,
search_fields, list_select_related, list_per_page,
list_max_show_all, list_editable, model_admin):
super(ItemChangeList, self).__init__(request, model,
list_display, list_display_links, list_filter,
date_hierarchy, search_fields, list_select_related,
list_per_page, list_max_show_all, list_editable,
model_admin)
# these need to be defined here, and not in ItemAdmin
self.list_display = ['action_checkbox', 'name', 'colour']
self.list_display_links = ['name']
self.list_editable = ['colour']
class ItemAdmin(admin.ModelAdmin):
def get_changelist(self, request, **kwargs):
return ItemChangeList
def get_changelist_form(self, request, **kwargs):
return ItemChangeListForm
admin.site.register(Item, ItemAdmin)
Now you all set to check the changes, run server and check django admin for Movie model. You can edit ManyToMany field directly from list display page.
Note : If you are going to use muliptle ManyToManyFields editable in list then, you need to set DATA_UPLOAD_MAX_NUMBER_FIELDS in settings.py .
You can easily add a custom view to your admin urls and add the required html/javascript/ajax. Here's the basics:
class ItemAdmin(admin.ModelAdmin):
# regular stuff
def render_foo(self, obj):
# add this to your list_display
html = '<stuff><input/submit action></stuff>'
return mark_safe(html)
def get_urls(self):
urls = super(ItemAdmin, self).get_urls()
extra_urls = patterns('',
(r'^process_foo/$', self.admin_site.admin_view(self.process_foo)),
)
return extra_urls + urls
def process_foo(self, request):
if not request.is_ajax():
raise Http404
foo = request.GET.get("attr")
# process m2m
# return some json

Validating data in Django ModelForm

And i have a simple modelform for Package
from models import Package
from django import forms
class PackageForm(forms.ModelForm):
class Meta:
model= Package
fields= ['name', 'version', 'url', 'description', 'arch', 'dependancies', 'conflicts', 'file']
How can i ask the modelform to check, within validation, if the file extension (class is FileField) is .sh for example?
is there a way to put this in modelform? of can i only manage it in a view?
Thanks
Edit:
Also, forgot to ask, the model has a Foreignkey to the auth User model... which is going to contain the current user.. how can modelform manage that?
Thanks again
Thanks for the answer! i'm getting hold of this.. although i encounter a problem
Package contains a foreignkey to django.contrib.auth.models User model,
When the form is processed how can i tell the modelform to pass the current user object to the model instance?
i thought of this...
views.py
def add(request):
if request.method == 'POST':
the_model= PackageForm(request.user, request.POST, request.FILES)
if the_model.is_valid():
the_model.save()
i overwrited the init in modelform:
from models import Package
from django import forms
class PackageForm(forms.ModelForm):
def __init__(self,user,*args,**kwargs):
super (PackageForm,self ).__init__(*args,**kwargs) # populates the post
self.fields['maintainer_name'].queryset = user # adds the user object passed by add in views.py
class Meta:
model= Package
fields= ['name', 'version', 'url', 'description', 'arch', 'dependancies', 'conflicts', 'file']
manteiner_name is the ForeignKey(User) object...
it gives me a keyerror :( that's not good...
Any solutions?
Thanks!
You should read the Django documentation on doing extra validation:
You just need to define a clean_file() method.