Django Admin Page – Create a link to list of objects, filtered by foreign key

i am learning Django right now and still struggling with it. I have two models: Database and DatabaseUser, linked with a foreign-key. In the admin page, I want to add a link to the list with databases, that directs me to a list with database-users of that specific database.

Python: 3.9; Django: 4.2.13

# models.py


class Database(models.Model):
    datenbank_name = models.CharField(max_length=300)
    datenbank_art = models.CharField(max_length=100)
    # ... (omitted some attributes)

    def __str__(self):
        return self.datenbank_name

class DatabaseUser(models.Model):
    datenbank = models.ForeignKey(Database, on_delete=models.CASCADE)
    user_name = models.CharField(max_length=300)
    # ... (omitted some attributes)

    def __str__(self):
        return self.user_name

My admin models are looking like this:

# admin.py

class PasswordInput(forms.ModelForm):
    passwort = forms.CharField(widget=forms.PasswordInput())


class DatabaseAdmin(admin.ModelAdmin):
    form = PasswordInput
    fieldsets = [
        ("Allgemein", {"fields": ["datenbank_name", "datenbank_art", "kunde", "host", "port"]}),
        ("Anmeldeinformationen", {"fields": ["user_name", "passwort"]}),
    ]
    
    list_display = ["datenbank_name", "kunde", "datenbank_art", "port", "erreichbar"]

admin.site.register(Database, DatabaseAdmin)



class DatabaseUserAdmin(admin.ModelAdmin):
    form = PasswordInput
    fieldsets = [
        ("Datenbank", {"fields": ["datenbank"]}),
        ("Anmeldeinformationen", {"fields": ["user_name", "passwort"]}),
        ("Datenbank-Rechte", {"fields": ["rechte"]}),
    ]
    list_filter = ["datenbank"]

    list_display = ["user_name", "rechte", "datenbank"]

admin.site.register(DatabaseUser, DatabaseUserAdmin)

Now I have tried couple of things and found 2 very similar questions on Stack Overflow. However i couldn’t get them to work in my code. The second one is not creating a link to the list of objects, but to the change-view (as far as I’ve understood).

  • How can I list all foreign key related objects in Django admin panel?
  • Link in django admin to foreign key object

From the first thread (How can I list all foreign key related objects in Django admin panel?) I have tried all three solutions. Unfortunately without success:

My attempt for first solution:

def users(self):
    return '<a href="/admin/db_manager/databaseuser/?datenbank__id__exact=%d">%s</a>' % (
    self.datenbank_id, self.datenbank)

users.allow_tags = True

list_display = ["datenbank_name", "users", "kunde", "datenbank_art", "port", "erreichbar"]

Errors:

  • In my code self.datenbank_id and self.datenbank are beeing highlighted by PyCharm, saying “Unresolved attribute reference ‘datenbank_id’ for class ‘DatabaseAdmin'”

  • Furthermore when I try to open the admin site, it says “users() takes 1 positional argument but 2 were given”

If I add obj to the function: def users(self, obj): The error is either “‘DatabaseAdmin’ object has no attribute ‘datenbank_id'” (if self.datenbank_id is used) or ‘Database’ object has no attribute ‘datenbank_id’ (if obj.datenbank_id is used)

Just can’t figure it out.

My attempt for the second solution:

# models.py 
def get_admin_url(self):
    return "/admin/db_manager/databaseuser/%d/" % self.id
# admin.py 
def databases(self, obj):
    html = ""
    for obj in DatabaseUser.objects.filter(datenbank__id_exact=self.id):
        html += '<p><a href="%s">%s</a></p>' % (obj.get_admin_url(), obj.title)
    return html

databases.allow_tags = True

list_display = ["user_name", "rechte", "datenbank", "databases"]

Errors:

  • PyCharm highlights self.id objects in DatabaseUser.objects.filter and self.id in the get_admin_url() function.
  • Similar other errors than with the first solution. E.g.: adding obj to function parameters

I have then tried a solution of the second link (Link in django admin to foreign key object) and: Surprise. I got something that at least loads:

def users(self, obj:DatabaseUser):
    link = reverse("admin:db_manager_databaseuser_change", args=[obj.pk])
    return mark_safe(f'<a href="{link}">{escape(obj.__str__())}</a>')

users.allow_tags = True

list_display = ["datenbank_name", "users", "kunde", "datenbank_art", "port", "erreichbar"]

Problem is, that the second thread about a slightly different problem. In the list view of the database a link is shown, as I wanted it, in an own column, next to each database.
However this link directs me to the change form, where I can make changes to the attributes of a specific user. Not the list as I wanted it.

I tried to change link = reverse("admin:db_manager_databaseuser_change", args=[obj.pk]) to link = reverse("admin:db_manager_databaseuser_changelist", args=[obj.pk]). But this will throw me an error:
Reverse for 'db_manager_databaseuser_changelist' with arguments '(2,)' not found. 1 pattern(s) tried: ['admin/db_manager/databaseuser/\Z']

I think one of the main problems for me here is, that I have started with Django like 1 Week ago and until now I can’t get my head around, how everything is connected.
I am a bit desperate right now. I would really appreciate any help, to get this fixed.

Greetings.

New contributor

carl_3000 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

1

From what I gather, you want to display all Database objects, with a column where a link would redirect to all DatabaseUsers objects referring to the selected Database. In Django admin, the view where you can see a table of all instances of a model is called the changelist view. So, translated in django admin grammar, what you want is a link in the Database changelist to the DatabaseUser changelist, filtered for the relevant Database.

Now, you want a link, so let’s have a look at how URLs are built. The changelist URL for any model yourmodel in the app yourapp is /admin/yourapp/yourmodel/. Filtering happens in the URL too, in Django syntax: /admin/yourapp/yourmodel/?my_field__gte=5 yields all yourmodel instances with a myfield value over or equal to 5.

You were nearly there with your first solution. As your errors point out, neither Database nor DatabaseAdmin have a datenbank_id attribute. However, your Database model has an (implicitly created) id attribute, so try:

from django.utils.safestring import mark_safe

def users(self, obj):
    return mark_safe(
        '<a href="/admin/db_manager/databaseuser/?datenbank__id__exact=%d">
            See list of users
        </a>' % (obj.id))

The mark_safe is there to ensure that the result is interpreted as HTML and not as text (try without, to see the difference).

From what I understand, your (corrected) second solution would give you a list of links to each relevant DatabaseUser, instead of a unique link to the list of all relevant DatabaseUsers. I don’t think it’s what you want.

Third solution: reverse("admin:db_manager_databaseuser_changelist") would give you the correct link to the DatabaseUser changelist, but I don’t think you can provide the filter this way (args is something else). You could still use it to rewrite the previous solution:

from django.utils.safestring import mark_safe
from django.urls import reverse

def users(self, obj):
    link = reverse("admin:db_manager_databaseuser_changelist")
    return mark_safe(
        '<a href="' + link + '?datenbank__id__exact=%d">
            See list of users
        </a>' % (obj.id))

Hope this helps.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật