I have a generic inline which I am attaching to certain models. It works fine, but the admin interface looks kind of ugly:
http://i.stack.imgur.com/dI3UH.png
As you can see, the same heading is repeated several times. In this instance I am only ever going to add one entry to the inline, which I have setup like so:
class PageMetaInline(generic.GenericStackedInline):
model = PageMeta
extra = 1
max_num = 1
Is there any way to remove the unnecessary header "Page Meta: #1" ?
You could override the admin template for stacked inlines for the PageMeta model.
Copy the original template (view current version in trunk on the Django site) to 'admin/yourapp/pagemeta/stacked.html', then customise by removing the html you do not wish to display.
Related
Im using a custom/extended ModelMultipleChoiceField and ModelChoiceIterator as per the answer to another question here
https://stackoverflow.com/a/73660104/20600906
It works perfectly but Im trying to amend the template used to generate the groups to apply some custom styling - but after poking around everywhere I cant find anything to overwrite.
I have gone through all the template files in
'\venv\Lib\site-packages\django\forms\templates\django\forms' and cannot find anything relating to the behaviour Im seeing on screen.
The 'groups' are wrapped in strong tags which is fine, but id like to find the file specifying this so I can overwrite with some bootstrap classes.
I've traced back through the class inheritance and the first widget specifiying a template is this one:
class Select(ChoiceWidget):
input_type = "select"
template_name = "django/forms/widgets/select.html"
option_template_name = "django/forms/widgets/select_option.html"
add_id_index = False
checked_attribute = {"selected": True}
option_inherits_attrs = False
Checking these files doesn't help as they don't appear to be the ones in use. Not sure where i'm going wrong?
Edit: Ive just realised the strong tags are coming from the cripsy forms tag. The templates probably make a lot more sense now, Ill go do some more digging.
If you have a StructBlock class (used inside a StreamField)... Can you still use the Wagtail panels to group some fields (eg MultiFieldPanel) and (ideally!) use the collapsible class on the panel to hide them in some kind of "Advanced" panel?
I have tried adding the block.TextBlock definitions into the array for a panel the, however neither the Panel nor the Fields appeared in the form.
I cant see anything in the docs about using Panels in StructBlocks:
https://docs.wagtail.io/en/v2.8.1/reference/pages/panels.html
https://docs.wagtail.io/en/v2.8.1/topics/streamfield.html
It's not possible to use panels inside StreamField blocks. However, by overriding form_template on your StructBlock class you can set up whatever HTML structure you like:
https://docs.wagtail.io/en/stable/advanced_topics/customisation/streamfield_blocks.html#custom-editing-interfaces-for-structblock
According to the docs:
http://django-grappelli.readthedocs.org/en/latest/customization.html#rearrange-inlines
The two classes for the placeholder are important. First, you need a class placeholder. The second class has to match the id of the inline–group.
All's well and good, I was able to set up my inlines fine, my issue is now - where does grappelli get the "id of the inline group" I can't find any reference, and pouring through the source code is offering me no solace.
Simply, I want to change the element-id that grappelli is using. Currently, it looks to me that it is taking the object name itself and converting to a lowercase name and appending set to the end. Do we have access to override the "id of the inline-group"?
Also, I am not 100% sure exactly how (or where) grappelli is doing this, it is definitely not documented... at all in fact.
Any help would be much appreciated.
It is the id of the inline element on HTML page. You can check the id of the default HTML inline element.
<div id="[related_name of ForeignKey]-group">
For example:
If in model "MyModel2", you have a ForeignKey like this:
my_model_1 = models.ForeignKey(MyModel1, related_name='my_model_2')
Then the id should be "my_model_2-group".
The id of the inline group is set in grappelli/templates/admin/edit_inline, in stacked.html line 5, or tabular.html line 6 (depending on which type of inline you're usng):
id="{{ inline_admin_formset.formset.prefix }}-group" >
You can override this by copying the file (stacked.html or tabular.html) into your template directory and setting the variable "template" to the file's new location e.g.:
# admin.py
class MyModelInline(admin.StackedInline):
template = 'path/to/stacked.html'
...
Then edit whatever you want in e.g. stacked.html.
I don't know if this is the best-practices way of doing this, but it's similar to what's done in the django tutorial.
i want to hide the plus + sign in some foreignkey fields of a specific model in django-admin interface. it's possible?
Thanks in advance!
The + is added when that foreign key's model can also be added in the admin, and is based on the permissions the user has on that model. If the user shouldn't be able to add those types of models, override has_add_permission on the foreign key's ModelAdmin (i.e. the one the plus sign would allow you to add), and return False for the appropriate conditions. The + will go away for any user not allowed.
If you just want to hide it for cosmetic purpose, I'd use a Javascript script that hides this '+' sign.
You can add custom Javascript sources to Admin Modelform's by using the Media inner class, as described in the docs. Something like this:
class MyModelAdmin(admin.ModelAdmin):
class Media:
js = ("js/hide_myfield_addlink.js",)
The Javascript source would look something like:
/* file: hide_myfield_addlink.js */
django.jQuery(document).ready(function() {
django.jQuery("#add_id_myfield").hide();
});
On the other hand, if those admin users should never be able to add such a model, don't give them the permission to add those. Then these add links will never be displayed.
Might as well do it in CSS:
.field-myfield .related-widget-wrapper-link {
display: none;
}
Or to disable it everywhere:
.related-widget-wrapper-link {
display: none;
}
Is there a straightforward, common way to apply custom styling on admin change list element depending on its properties?
update
To be more precise: let's say I have a simple model object.
Foo
field1
field2
field3
#property
property1()
#property
property2()
ModelAdmin.list_display is defined as a subset of the available fields, so not every attribute (field/property) is displayed in the change list table.
I'd like to apply custom CSS class to the object's row when certain condition is fulfilled, for example: if foo_instance.property1 is True then add class bar to the corresponding tr element.
Now copy the template admin/base_site.html from within the default Django admin template directory (django/contrib/admin/templates) into an admin subdirectory of whichever directory you're using in TEMPLATE_DIRS. For example, if your TEMPLATE_DIRS includes "/home/my_username/mytemplates", as above, then copy django/contrib/admin/templates/admin/base_site.html to /home/my_username/mytemplates/admin/base_site.html. Don't forget that admin subdirectory.
Note that any of Django's default admin templates can be overridden. To override a template, just do the same thing you did with base_site.html -- copy it from the default directory into your custom directory, and make changes.
from django's tutorial
What exactly do you mean by "change list element" and "it's properties"? Using CSS 2 or CSS 3 selectors you can do some things. Otherwise, you might be able to do it easily using jQuery (or whatever). Since it is merely presentation related, I think this would be the cleanest solution.
Old question but if you stumble across it, the following tips might be helpful.
You can use django-liststyle to customise your admin changelist rows.
It's quite simple to implement your example:
class FooAdmin(admin.ModelAdmin, ListStyleAdminMixin):
...
def get_row_css(self, obj, index):
if obj.property1:
return 'bar'
return ''
Django Suit (not free) also offers "List row and cell attributes" style customisation