Django Admin ForeignKey field widget options and inconsistent defaults - django

I have a model that has foreign keys, and in the admin those FKs render as drop-down lists. However, some of them show buttons for 'add', 'edit', and 'delete' of the elements in the related table, and others do not. I cannot figure out what is different between the fields such that some render one way and some render a different way.
My ideal situation is that those buttons do not render for any foreign keys, that editing one model is restricted to just changes on that entity itself.
I see that Django ultimately selects the RelatedFieldWidgetWrapper for these fields. I can set can_add_related, can_change_related, and can_delete_related on this widget, but I don't see how to easily pass these as options for these fields so that they are all consistent.
How do I manage turning these options on and off in the admin?

New a staff user(not superuser) in admin,assume model A has foreignkey named model B,assign add/change/delete perms of model A and add perm of model B to that user,use that user to login admin,you can and only can add model B in admin panel or RelatedFieldWidgetWrapper.Because can_xxx_related is cal in admin by perms by:
wrapper_kwargs.update(
can_add_related=related_modeladmin.has_add_permission(request),
can_change_related=related_modeladmin.has_change_permission(request),
can_delete_related=related_modeladmin.has_delete_permission(request),
)
code in django\contrib\admin\options.py\line 162

Related

Django admin for categories and objects

I have objects and catetories in Django and object has ForeignKey to Category.
In Admin user must first create categories and then create objects choosing category from list.
What I want to have is file manager metaphore: User opens list of categories, clicks "create object here" and creates one like we do it with folders and files.
I wonder if Django has some application for it. Does it?
I know about inlines, but I do not want to edit object on the same page, I want to have list of them.
It is similar to Django: adding an "Add new" button for a ForeignKey in a ModelForm but I do not have ModelForm, I speak about admin
In Django admin, you can use inlines, example:
class OBJECTSInline(admin.TabularInline):
model = OBJECTS
extra = 0
class CATEGORYAdmin(admin.ModelAdmin):
list_per_page = 10
inlines = [OBJECTSInline,]
admin.site.register(CATEGORY, CATEGORYAdmin)
If you register both your models in the Django admin, you will see that when creating/editing an object with foreign key to Category, there will be a dropdown for the foreign key value, which lists existing values, and next to it, buttons for editing/deleting the selected value, or for creating a new Category:
That seems to be what you're asking for - it's already there in the admin as soon as you register the relevant models.

Replace foreign key dropdown with textbox with add/edit icon - Django

Related to foreign key fields in the Django Admin, the default display
element is a drop down list box containing all of the foreign key
items from the related model. I my app it will contain thousands of items and I am looking to change the admin interface and have it use a text box instead of the populated drop down.
Looking for textbox with add/edit icon next to it, so that we dont get populated values, we just directly add or edit.
Is there any way around to achieve it.
What you are looking for is raw_id_fields
class ArticleAdmin(admin.ModelAdmin):
raw_id_fields = ("newspaper", )
By default, Django’s admin uses a select-box interface (<select>)
for fields that are ForeignKey. Sometimes you don’t want to incur
the overhead of having to select all the related instances to display
in the drop-down.
raw_id_fields is a list of fields you would like to change into an
Input widget for either a ForeignKey or ManyToManyField:
NOTE: The raw_id_fields Input widget should contain a primary key if the field is a ForeignKey or a comma separated list of values if the field is a ManyToManyField. The raw_id_fields widget shows a magnifying glass button next to the field which allows users to search for and select a value:
You can read the docs here
You can try use custom Form and realize custom Widget on this form field. (I use for this desicion 3rd party library django_select2)
from django import forms
from django_select2.forms import ModelSelect2Widget
class KeyWidget(ModelSelect2Widget):
model = ModelToKey
search_fields = ['field__icontains']
def label_from_instance(self, obj):
return u'{}'.format(obj.field)
class CustomForm(forms.ModelForm):
class Meta:
model = ModelWithKey
fields = ('foreign_key_field')
widgets = {
'foreign_key_field': KeyWidget(attrs={'style': 'width:550px'}),
}
In also you can overload Form __init__ for customize queryset of objects for choosing in this field.

Column Sorting in Django Admin

Hey I have a model UserProfile which has a OneToOneField relationship to the model User. In the adminpage I use list_display property to display some of the fields of UserProfile in the same place where User is displayed. They are displayed well but unfortunately they are not sortable like the models from User. I can click on the column heading in order to sort the columns which belong to User but not the ones that are from UserProfile how do you make them clickable and sortable?
You'll need to add the admin_order_field property to your columns.

Django admin foreign key field filtering

I have client model which has a foreign key field to a country model.
So in Django admin, when I create a client and I select the country where this client belongs to. but the problem is the select list is too long(too many countries on this planet). Sometimes it takes just too long to get the one I need.
So I wonder if there is other widget in djano admin that provides a select-input-combo widget.
When I type in the input and it will filter out the right one for me to select.
Hope you can understand what I need here.
did you see raw_id_fields ?
you would do in admin.py something like:
class ClientAdmin(admin.ModelAdmin):
raw_id_fields = ("country",)
admin.site.register(Client, ClientAdmin)
then select widget will become something like:
Since Django 2.0 there is autocomplete_fields. From the documentation:
autocomplete_fields is a list of ForeignKey and/or ManyToManyField fields you would like to change to Select2 autocomplete inputs.
and
The Select2 input looks similar to the default input but comes with a search feature that loads the options asynchronously. This is faster and more user-friendly if the related model has many instances.
Note that you need to define search_fields in the related object's ModelAdmin since it is used by the widget.

admin site doesn't show object fields

I have a model with a PointField from django.contrib.gis.db.models . This somehow doesn't let the admin site show the objects with a nice table of fields and values. Instead it displays one field named after the model name. The values are just a bunch of ' object'. With the name of the model. If I click the object I can edit it fine. It would be nice however to be able to filter and see the field values at the admin/ page itself.
Since PointField does not have a __unicode__ attribute, for the proper name to show up, you can register a new admin model object.
Now, in the admin's list_display,
class PointFieldAdmin(admin.ModelAdmin):
list_display = ('name', 'field_x', 'field_y', ...)
admin.register(PointField, PointFieldAdmin)
More on admin models registering here