How to show another list_display inside fieldsets? - django

When clicking on original list_display item I want it to show another list_display(containing of models that have ForeignKey to original item) instead of normal fieldsets.
I can get it working but only with inlines, is it possible to display it as another list_display?
I am using Django Suit to get tabs:
class KWInline(admin.TabularInline):
model = Url
list_display = ('title', 'url', 'pda', 'upa')
extra = 0
suit_classes = 'suit-tab suit-tab-cities'
class KWAdmin(ImportExportModelAdmin):
resource_class = KWResource
list_display = ('Keyword', 'searches', 'cpc', 'comp'...)
inlines = [KWInline]
fieldsets = [
(None, {
'classes': ('suit-tab suit-tab-cities',),
'fields': ['Keyword', 'searches', 'cpc']}),
... .... ...
suit_form_tabs = (('general', 'General'), ('cities', 'Cities'),
('flag', 'Flag'), ('info', 'Info on tabs'))
I tried changing admin.TabularInline to normal admin and get expected error(calling inlines without proper class inheritance)
It looks like this, any ideas on how to change inlines to list_display?:

Related

ModelMultipleChoiceField field returning no value

class DocumentForm(forms.ModelForm):
model = Document
starred_by = forms.ModelMultipleChoiceField(queryset=User.objects.all())
class Meta:
widgets = {
'created_by': AutocompleteSelect(
Document._meta.get_field('created_by').remote_field,
admin.site,
attrs={'data-dropdown-auto-width': 'true'}
),
'organisation': AutocompleteSelect(
Document._meta.get_field('created_by').remote_field,
admin.site,
attrs={'data-dropdown-auto-width': 'true'}
),
'starred_by':AutocompleteSelectMultiple(
Document._meta.get_field('starred_by').remote_field,
admin.site,
attrs={'data-dropdown-auto-width': 'true'}
)
}
Update:
I have read a bit about the select2 library but I am having trouble understanding how do I integrate it with Django-admin my requirements mostly are searchable select dropdown for foreign keys and multi-select dropdowns for many-to-many fields but these fields I want in the Django admin panel in my apps, any help will be appreciated, thanks in advance
This is how I solved it , I used Django's native search fields which uses Sleect2 under the hood
class OrganisationAdmin(admin.ModelAdmin):
list_display = ('name','address')
autocomplete_fields = ['products']
search_fields = ['name__iexact']
# autocomplete_fields = ['']
class ProductAdmin(admin.ModelAdmin):
search_fields = ['name']

How to change the layout and fields disposition of Django's Admin forms?

I have a simple model of a Student which is registered to the admin through a admin.ModelAdmin.
The admin change form of this model looks like this:
I'd like to change the layout of this form a little so that a few fields could be in the same line, like so (edited in Paint):
Is there something I could do without overriding the default templates? And if there isn't, what's the best way?
Thanks in advance.
You can use fields attribute in ModelAdmin like this:
#admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
fields = (
('no_student', 'last_name', 'first_name),
'course',
'sex',
'id'
)
Fields grouped in one sub-tuple or sub-list will be shown in one line. You can create more than one groups like this.
You can do this by using fieldsets.
class StudentAdmin(admin.ModelAdmin):
fieldsets = (
(None, {
'fields': (('no_student', 'last_name', 'first_name), 'course', 'sex', 'ID')
}),
...
)
Please note i have wrapped the fields which should be shown in single line in same tuple.
Reference

default Admin List filter not selected but implemented

I have in my admin a list of object representing "Projects" which have filters applied to them. Each "Project" can either be Open or Closed (Defaulting to open). My problem is that the objects are filtered by default but the applied filter option (yes/no) isn't highlighted until manually selected.
I also looked at this but the solution wouldn't work for me:
Default filter in Django admin
EDIT: Added code.
class ProjectAdmin(admin.ModelAdmin):
save_on_top = True
list_display = ["__unicode__", "created_at", "updated_at", "region", "get_main", "get_code", related_information]
list_display_links = ("__unicode__",)
search_fields = ["short_title_eng"]
form = ProjectForm
ordering = ('project_number',)
change_form_template = "project/project_change_form.html"
add_form_template = "project/project_add_form.html"
readonly_fields = ["project_number"]
list_filter = (ProjectStatusFilter, CountryFilter, RegionFilter, ProjectAEI, ProjectCropType)
fieldsets = (
(None, {
'fields': ('short_title_eng', 'project_number', 'close_project'),
'classes': ['wide', ],
}),

Django editable=False and still show in fieldsets?

I have an image field in my models.py...
qr_image = models.ImageField(
upload_to="public/uploads/",
height_field="qr_image_height",
width_field="qr_image_width",
null=True,
blank=True,
editable=False
)
When it's editable=False I get a nasty error when trying show it. I don't want the field editable, however I do want the image to show in admin 'edit' page i.e. fieldsets
I'm new to Django, can someone tell me if this is possible and point me in the right direction here?
thank you.
If you have a ModelAdmin like this:
class MyModelAdmin(admin.ModelAdmin):
fieldsets = [
('Fieldset', {'fields': ['model_field', 'another_field', 'readonly_field']}),
]
where readonly_field has editable=False or if it is a DateTimeField with auto_now_add=True then visiting the admin page for your model will result in a field not found error.
To include a readonly field in your fieldsets, include readonly_fields like this:
class MyModelAdmin(admin.ModelAdmin):
fieldsets = [
('Fieldset', {'fields': ['model_field', 'another_field', 'readonly_field']}),
]
readonly_fields = ('readonly_field',)
An easy way to accomplish this is to make the field read-only in the ModelAdmin: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields

Can't display DateField on form with auto_now = True

I have a model with auto_now, and auto_now_add set for Update and Create fields:
class HotelProfiles(models.Model):
fe_result_id = models.AutoField(primary_key=True)
fe_created_date = models.DateTimeField(verbose_name='Created',
blank=True,
auto_now_add=True)
fe_updated_date = models.DateTimeField(verbose_name='Updated',
blank=True,
auto_now=True)
In the Admin it displays both fields but leaves them uneditable. They
don't seem to be passed to my form to be rendered. I don't want them
to be editable, but I would like to display at the top of my form.
How can I do this?
This is in my HotelProfilesAdmin class:
readonly_fields = ('fe_result_id', 'fe_created_date', 'fe_updated_date', 'fe_owner_uid')
#date_hierarchy = 'lto_end_date'
fieldsets = (
("Internal Use Only", {
'classes': ('collapse',),
'fields': ('fe_result_id', 'fe_created_date', 'fe_owner_uid', 'fe_updated_date', 'fe_result_status')
}),
Make the fields you want readonly
explicitly override what fields are available in this admin form (readonly fields will be present but readonly)
Example:
from django.contrib import admin
class HotelProfilesAdmin(admin.ModelAdmin) :
# Keep the fields readonly
readonly_fields = ['fe_created_date','fe_updated_date']
# The fields in the order you want them
fieldsets = (
(None, {
'fields': ('fe_created_date', 'fe_updated_date', ...other fields)
}),
)
# Add your new adminform to the site
admin.site.register(HotelProfiles, HotelProfilesAdmin)
For the benefit of others, I figured out a way to do this. I'm new to Django, so if there is a better way, I'd be interested in hearing it. The view code is below. I wasn't sure if Django was not returning the fields from the query, and I found out that it was. So, something in the renderering of the form that I don't understand removed those fields so they couldn't be rendered. So, I copied them to a dict called read_only before rendering and passed it along.
try:
hotel_profile = HotelProfiles.objects.get(pk=hotel_id)
read_only["created_on"] = hotel_profile.fe_created_date
read_only["updated_on"] = hotel_profile.fe_updated_date
f = HotelProfileForm(instance=hotel_profile)
#f.save()
except:
f = HotelProfileForm()
print 'rendering blank form'
return render_to_response('hotels/hotelprofile_form.html', {'f' : f, 'read_only': read_only}, context_instance=RequestContext(request))