Django admin, hide +Plus sign to specific foreignkey field - django

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;
}

Related

In the Wagtail how to disable certain admin menu items for the certain users?

For the group of users I want to disable some menu items. I thought I will use the following:
from wagtail.contrib.modeladmin.options import ModelAdmin as WModelAdmin
class WPartnerAdmin(WModelAdmin):
...
def get_menu_item(self, order=None):
menu_item = super().get_menu_item(order=order)
# if (user_discrimination_logic):
# menu_item.is_shown = lambda *a: False
return menu_item
But it seems that I don’t have access to the request object in the Wagtail ModelAdmin, therefore don’t know how to extract the user data. Is there a way?
You can use Wagtail's Hooks functionality, particularly the construct_main_menu hook:
Create a wagtail_hooks.py file in your corresponding application, with something like the following (from the Wagtail Docs):
from wagtail.core import hooks
#hooks.register('construct_main_menu')
def hide_explorer_menu_item_from_frank(request, menu_items):
if request.user.username == 'frank':
menu_items[:] = [item for item in menu_items if item.name != 'explorer']
Wagtail's built in permission system stops the user from viewing the actual modeladmin objects, but the available options still show up in the menu even for groups without permission to view them. When they try to view the objects, people without view permission are sent to the login screen and told they have insufficient permission.
If you want to hide admin menu items for particular users that are all part of a specific group, or even multiple groups, you can do it using wagtail's construct_main_menu hook. Add a wagtail_hooks.py file in the app folder. Menu items are edited in place.
To remove two menu items called "secrets1" and "secrets2" for users that are in any of "regular_user" or "bad_user" groups, you could do something like this:
from wagtail.core import hooks
#hooks.register('construct_main_menu')
def hide_explorer_items_from_users(request, menu_items):
if request.user.groups.filter(name__in=["regular_user", "bad_user"]):
menu_items[:] = [
item for item in menu_items if item.name not in ['secrets1', 'secrets2']
]
This is fine for removing items, but if plan on adding menu items this way, Wagtail's Hooks Documentation warns you that menu items added this way will be missing associated javascript includes, so you should use the #register_admin_menu_item hook for adding items instead.
For most purposes, this can be done without any code changes, through the permissions system.
Under Settings -> Groups, define a group with permissions over the objects they should be able to edit (such as pages, images and documents), and ensure the 'Can access Wagtail admin' permission is checked. Then, in Settings -> Users, go to the Roles tab for each user and add them to that group (and ensure Administrator is unchecked). Any menu items that the user doesn't have permission over will be hidden.

Add hidden field at runtime

In Sitecore WFFM(Web Form for Marketers) - Can we add hidden field at runtime - i.e. on Submit Action and assign some value to the hidden field.
I also want to reuse this value if there is an exception on the form and user resubmits the form.
Product Details - 7.2 rev. 141226 , Web Forms for Marketers 2.4 rev.140117
As the very simple, you may create hidden field like this (of course, you may provide alternative and more complex bespoke behavior for your hidden field):
public class HiddenField : SingleLineText
{
protected override void DoRender(System.Web.UI.HtmlTextWriter writer)
{
this.textbox.Parent.Parent.Visible = false;
base.DoRender(writer);
}
}
With the next step you need to register that field with WFFM. In order to do that just create an item for your new field:
/sitecore/system/Modules/Web Forms for Marketers/Settings/Field Types/Custom/Hidden Field
Within that item you specify assembly and class name for that hidden field, as is very common way to Sitecore.
So far, so good. Now you can use your hidden field as others, including adding them programmatically.
P.S. Unfortunately, I do not have an example of code for adding fields programmatically at the moment. However you can try finding that yourself with Reflector, dotPeek or any other disassembling tool. Library should be in your \bin folder already, called Sitecore.Forms.Core.dll

django admin list_filter too long

I have a list_filter with loads of sectors. This list, on the right side of the page, is too long.
Can I use an input select field instead since I can't choose more than one sector?
I have seen this before, screenshots, but I can not find the way to do this.
edit:
I have a custom FilterSpec not a list_filter
You can write your own custom FilterSpec (custom admin list filter).
This feature is not part of the Django code yet; it is planned for version 1.2. You'll need to apply this patch to the Django code: http://code.djangoproject.com/ticket/5833.
There are many examples on stackoverflow on how to do that, e.g: https://stackoverflow.com/a/1294952/342473.
http://lincolnloop.com/blog/2011/jan/11/custom-filters-django-admin/
The long list that you said comes from the default template 'admin/filter.html', in django/contrib/admin/templates/admin/filter.html, of builtin ListFilters.
There are several ways to customize it:
Globally override 'admin/filter.html'. Render select tag instead of ul tag if the count of choices hit certain limit. This affects all list filters in admin. The select tag should have onchange event handler like
<select ... onchange="location.href=this.options[this.selectedIndex].value">
Set template attribute in your specific ListFilter instance, to the name of the customized filter template. The content of the template is like #1. Django 1.4+ is required for this.
Add javascript in the ModelAdmin instance to convert HTML content inside the ul tag to select tag as soon as DOM has been fully loaded.
This is how i resolved it (jQuery):
$('#changelist-filter ul').each(function(){
var maxlength = 10;
if ($(this).children().length > maxlength )
{
var list=$(this),
select=$(document.createElement('select')).insertBefore($(this).hide());
$('>li a', this).each(function(){
console.log($(this).parent().attr('class'));
var target=$(this).attr('target'),
option=$(document.createElement('option'))
.appendTo(select)
.val(this.href)
.attr('selected', $(this).parent().attr('class'))
.html($(this).html())
.click(function(){
if (target==='_blank'){
window.open($(this).val());
}
else{
window.location.href=$(this).val();
}
});
});
list.remove();
}
});

Customising specific fields in Django Admin change form

I have a couple of fields in my model that to which I wish to add a link that will allow the user to search for names/files (external from the application's database).
So what I would like is:
Field name: [text box] - LINK
Is there a straightforward django way of achieving this?
Cheers.
You need to change the widget that the form field uses to display the models information. You basically add some html after the input to link to where you want.
Here's some code I put together to create a widget that displays how many characters are left for a CharacterField so it's similar to what you are looking to do:
https://github.com/pastylegs/django-widget-charsleft/blob/master/widget_charsleft/widgets.py

Styling certain admin change list rows

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