Show reverse ManyToMany entries in Django Admin page - django

In the classical example of Articles/Publications, when I create a Publication record in Admin page, I would like to be able to add existing Articles to that Publication. How can I do that?
I tried following:
class PublicationAdmin(admin.ModelAdmin):
articles = Article.objects.all()
admin.site.register(Publication, PublicationAdmin)
though I do not see any articles to select at all.
I can do the other way around, when I add a new article, I can select a publication by adding
class ArticleAdmin(admin.ModelAdmin):
fieldsets =[('Publications', {'fields': ['publications']})]

You need to define an InlineModelAdmin on the through model, in your case the through model is Publication.article_set.through. See the docs.

Related

django: Make better looking multiple select menus in admin as displayed in auth>user tables

I have a User model that has these two fields:
permissions = models.ManyToManyField(Permission)
groups = models.ManyToManyField(Group)
I register the model in the admin. When I view the user model that I made in the admin section I get a multiple select menu that looks like this.
I would much prefer the much better-looking menu like the one that is in the auth user model that comes built into Django admin (looks like this)
Any ideas on what I need to do to be able to access this sort of select menu?
Thanks for your help.
Django newb from PHP (finally)
Use filter_horizontal (or filter_vertical) field in your admin class.
For example:
#admin.register(User)
class UserAdmin(admin.ModelAdmin):
...
filter_horizontal = 'groups', 'permissions', 'any_other_m2m_field'
...
Also link to Django docs:
https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.filter_horizontal

How to make django screen dynamic with user choices?

So i work in a company and we constantly need to add view fields for the user, I would like to know if there is a way to make this option available to the end user, for example a dropdown with the options that the model admin where he is allowing.
Today we use the django way of doing admin, for example:
list_display = (
'course',
'class',
'discipline',
'teacher',
'start_date',
'end_date'
)
I don't know if this what you are looking for, but give a try: How can I dynamically specify the "list_display" attribute of a django ModelAdmin class?
A kind regard
Emilio

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.

Filter foreignkey choices in Admin changelist view

I got two models which are related via ForeignKey in Django. (I am using Django 1.3)
Class Person(models.Model):
# some fields here like name, gender, etc...
Class Course(models.Model):
# some fields here
contact = models.ForeignKey(Person, blank=True, null=True)
In the admin changelist view for the Courses I want to be able to filter the Courses by the ForeignKey contact. In the admin.py i got:
class CourseAdmin(admin.ModelAdmin):
list_filter = ('contact',)
This work very well. I can filter the Courses by all available Contacts. Now I would like to display only those contacts that actually have a Course attached to them.
I read here on SO to implement CustomFilters by creating a custom FilterSpec. I dont know wheter this is the right direction, because I only need to further filter the queryset that is used to display the choices for the contacts.
In the shell I get the desired queryset by this:
contacts=Person.objects.filter(course__in=Course.objects.all()).distinct()
I already read that you can easily achieve this in 1.4, but I am still bound to 1.3
Can someone please point me into the right direction? Thank you!
Django 1.3 also supports Filters, but the filter classes were moved/renamed in 1.4. And using a FilterSpec is the way to achieve your goal. You not only need to filter the queryset, but to handle properly the applied filter from QueryString. So go ahead with filters. Here is a very good snippet, that handles the FK filtering, and has decent options: http://djangosnippets.org/snippets/2260/

Admin, two links to different views?

in django admin the views that show the register's just have
a link to "edit", but what happen if a need an extra(S) links to
another views?
for example:
i have view that show the list of registered People, the nick is
linking to the Edit page (the normal way of Django), but i need
another links that will show me the "articles" of the people and
another the "comments" of the people.
how ill make this with django admin?
Thanks
(I'm assuming some field names from your models to answer)
Make the author field from "comment" searchable:
class CommentAdmin(admin.ModelAdmin):
search_fields = ("=author",)
Use list_display and HTML to control what's displayed on the people's list admin page:
def comments(obj):
return ('comments' % obj.name)
comments.short_description = 'comments'
comments.allow_tags = True
class PeopleAdmin(admin.ModelAdmin):
list_display = ("name", comments,)
And change /admin/pathto/comments/ to whatever your comment's admin list page is.
Basically you're going to direct your users to the comments search result page.