Opened 18 years ago
Closed 15 years ago
#2583 closed defect (worksforme)
can't use ForeignKey in list view (class Admin: list_display)
Reported by: | 235 | Owned by: | nobody |
---|---|---|---|
Component: | contrib.admin | Version: | dev |
Severity: | normal | Keywords: | |
Cc: | jos@… | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
If we'll use next code:
class Articles(models.Model): .... author = models.ForeignKey(Authors, blank=True, null=True, verbose_name='Автор статьи') #models.CharField('Автор статьи', maxlength=100, blank=True) .... class Admin: list_display = ('pub_date', ... 'author')
The list view of objects will be broken in header - there would be no header for this ForeignKey. In django/contrib/admin/templates/admin/change_list_result.html defined:
<th{{ header.class_attrib }}>
and actualy it renders into (with TEMPLATE_STRING_IF_INVALID = "TEMPLATE_STRING_IF_INVALID" in settings.py):
<thTEMPLATE_STRING_IF_INVALID>
ForeignKey field lacks this attribute
Change History (15)
comment:1 by , 18 years ago
Version: | → SVN |
---|
comment:2 by , 18 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
comment:3 by , 18 years ago
Resolution: | wontfix |
---|---|
Status: | closed → reopened |
Whoop, should be marked as a "worksforme," not "wontfix."
comment:4 by , 18 years ago
Resolution: | → worksforme |
---|---|
Status: | reopened → closed |
comment:5 by , 18 years ago
Resolution: | worksforme |
---|---|
Status: | closed → reopened |
Same problem here, an exmaple
class Content(models.Model): body = models.CharField(maxlength=1024) class Rating(models.Model): body = models.CharField(maxlength=1024) severity = models.IntegerField() type = models.CharField(maxlength=128) application = models.CharField(maxlength=128) class Admin: list_display = ('type', 'severity', 'body', 'application') def __str__(self): return "%s" % (self.type) class Meta: verbose_name_plural = "Ratings" class Message(models.Model): content = models.ForeignKey(Content) rating = models.ForeignKey(Rating) body = models.CharField(maxlength=1024) date = models.DateTimeField(auto_now=True) errclass = models.CharField(maxlength=128) class Admin: list_display = ('errclass', 'body') def __str__(self): return "%s" % (self.body) class Meta: verbose_name_plural = "Messages"
When adding 'content' or 'rating' to the list_display of Messages, the admin view is empty, i.e. no list is generated. Maybe something to do with the fact that the Message model contains TWO foreign keys?
comment:6 by , 18 years ago
Resolution: | → worksforme |
---|---|
Status: | reopened → closed |
I've loaded this exact model, tried it with and without TEMPLATE_STRING_IF_INVALID set, and the list of Messages on the admin site renders fine. If I add content and rating to list_display, I get two extra columns in the table as expected.
comment:7 by , 18 years ago
Resolution: | worksforme |
---|---|
Status: | closed → reopened |
I've just started a clean django project + app (django SVN trunk) and I can reproduce this bug on both windows and linux. The code to reproduce is as follows:
models.py
from django.db import models from django.contrib.contenttypes.models import ContentType class Tag(models.Model): name = models.SlugField(unique=True, maxlength=80) class Admin: pass def __str__(self): return self.name class DaoTag(models.Model): tag = models.ForeignKey(Tag) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = models.GenericForeignKey() class Admin: list_display = ('tagged_on', 'content_type', 'tag') def tagged_on(self): return str(self.content_type.model_class().objects.get(id=self.object_id))
Relevant parts of settings.py:
TEMPLATE_STRING_IF_INVALID = 'XXX MISSING VARIABLE XXX' INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', 'missing_var', )
Resulting HTML code:
<table cellspacing="0"> <thead> <tr> <thXXX MISSING VARIABLE XXX> <-----------------------! Tagged on </th><th> <a href="?ot=asc&o=1"> Content type </a></th><th> <a href="?ot=asc&o=2"> Tag </a></th> </tr> </thead> <tbody>
Screenshot of admin:
http://bram.smartelectronix.com/tmp/admin.png
As the original poster mentioned, it's header.class_attrib which is missing...
comment:8 by , 17 years ago
( I just saw that it's even easier to reproduce this bug: it happens in the flatpages admin. )
comment:9 by , 17 years ago
Am I missing something here, or is this just an instance of the (documented) fact that TEMPLATE_STRING_IF_INVALID
breaks various parts of the admin? So long as TEMPLATE_STRING_IF_INVALID
is an empty string, everything works fine. If you set it to anything else you start seeing weird stuff in places that rely on the silent failure of non-existent variables (and the docs recommend using TEMPLATE_STRING_IF_INVALID
only as a temporary debugging measure for this very reason).
comment:10 by , 17 years ago
Cc: | added |
---|
I have this same problem, the admin page remains blank when using a foreignkey in list_display AND there are multiple foreignkey's.
I have TEMPLATE_STRING_IF_INVALID unset.
My problem can be triggered with the following model.
class Function(models.Model): description = models.CharField(maxlength=255) subdescription = models.CharField(maxlength=255, blank=True) version = models.CharField(maxlength=20) functionclass = models.ForeignKey(Functionclass, db_column='servermanagmentApp_functionclass_id') # loadbalanceIpAddress = models.ForeignKey(Loadbalanceipaddress, db_column='servermanagmentApp_loadbalanceipaddress_id') # logicalvolume = models.ForeignKey(Logicalvolume, db_column='servermanagmentApp_logicalvolume_id') def __str__(self): # if hasattr(self, "loadbalanceIpAddress") and str(self.loadbalanceIpAddress) != "0.0.0.0:0": # return "%s %s (%s)" % (self.description, self.subdescription, self.loadbalanceIpAddress) # else: return "%s %s" % (self.description, self.subdescription) class Meta: ordering = ('description', ) class Admin: pass list_display = ('description', 'subdescription', 'version', 'functionclass') list_filter = ('functionclass', ) class Functionclass(models.Model): description = models.CharField(maxlength=255, core=True) def __str__(self): return self.description class Admin: pass class Loadbalanceipaddress(models.Model): ipaddress = models.IPAddressField() port = models.PositiveSmallIntegerField() class Meta: ordering = ('ipaddress', 'port', ) class Admin: pass
As long as i keep either loadbalanceIpAddress or logicalvolume commented everything works.
But when either of those are uncommented (creating multiple foreignkeys) a blank list is generated by the admin.
As can be seen in the provided screenshots, the header and contents of the list fall away, the footer is still there.
http://brick29.hyves.org/86450001-86500000/86474901-86475000/86474961_6_c6aH.jpeg
http://brick29.hyves.org/86450001-86500000/86474901-86475000/86474962_6_keG9.jpeg
Following is the html source of the page with the empty list.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en-us" xml:lang="en-us" > <head> <title>Select function to change | Django site admin</title> <link rel="stylesheet" type="text/css" href="/media/css/changelists.css" /> </head> <body class="change-list"> <!-- Container --> <div id="container"> <!-- Header --> <div id="header"> <div id="branding"> <h1 id="site-name">Django administration</h1> </div> <div id="user-tools">Welcome, <strong>root</strong>. <a href="../../doc/">Documentation</a> / <a href="../../password_change/">Change password</a> / <a href="../../logout/">Log out</a></div> </div> <!-- END Header --> <div class="breadcrumbs"><a href="../../">Home</a> › Functions</div> <!-- Content --> <div id="content" class="flex"> <h1>Select function to change</h1> <div id="content-main"> <ul class="object-tools"><li><a href="add/" class="addlink">Add function</a></li></ul> <div class="module filtered" id="changelist"> <div id="changelist-filter"> <h2>Filter</h2> <h3> By functionclass </h3> <ul> <li class="selected"> <a href="?">All</a></li> <li> <a href="?functionclass__id__exact=1">MySql</a></li> <li> <a href="?functionclass__id__exact=2">www</a></li> <li> <a href="?functionclass__id__exact=3">daemons</a></li> <li> <a href="?functionclass__id__exact=4">squid</a></li> <li> <a href="?functionclass__id__exact=5">chat</a></li> <li> <a href="?functionclass__id__exact=6">loadbalancer</a></li> <li> <a href="?functionclass__id__exact=7">storage</a></li> <li> <a href="?functionclass__id__exact=8">sysadmin</a></li> <li> <a href="?functionclass__id__exact=9">ip-telephony</a></li> <li> <a href="?functionclass__id__exact=10">brick</a></li> <li> <a href="?functionclass__id__exact=11">mail</a></li> <li> <a href="?functionclass__id__exact=12">bricksbackuphead</a></li> </ul> </div> <p class="paginator"> <span class="this-page">1</span> <a href="?p=1" class="end">2</a> 182 functions <a href="?all=" class="showall">Show all</a> </p> </div> </div> <br class="clear" /> </div> <!-- END Content --> <div id="footer"></div> </div> <!-- END Container --> </body> </html>
comment:11 by , 17 years ago
Above problem as described by me was the result of errors in the consistency of the loaded dataset.
The database query therefor generated an empty result set when the loadbalancerip table was included in the join.
Still i think this should have generated a message, informing that there where no results to display.
Iam sorry for the false report
comment:12 by , 17 years ago
Resolution: | → worksforme |
---|---|
Status: | reopened → closed |
worksforme -- all the reported cases are either TEMPLATE_STRING_IF_INVALID or messed up data.
comment:13 by , 16 years ago
This is definitely fixed in trunk now, but for anyone stumbling across it on older Django: another way to trigger this is to have two foreign keys to the same table, one of them with null=True
and the other set in list_display
(older versions of Django will not do the proper join to make this work).
follow-up: 15 comment:14 by , 15 years ago
Resolution: | worksforme |
---|---|
Status: | closed → reopened |
Reproducible in Django 1.1.1.
Just to be sure :
TEMPLATE_STRING_IF_INVALID =
Model works perfect.
If I refer a FK in list_display
the whole row is gone !
Nothing is displayed. Screen sais i should see 15 records,
there ain't any not even in the HTML.
So i had to reopen ticket.
comment:15 by , 15 years ago
Resolution: | → worksforme |
---|---|
Status: | reopened → closed |
Replying to attila_forgacs:
The original problem here was apparently due to having TEMPLATE_STRING_IF_INVALID set to something other than an empty string, and it involved incorrect display, not all of the entries that should be there not being displayed. Thus, you seem to be having a different problem, not this one.
Plenty of people use ForeignKeys in list_display; this feature is not fundamentally broken. There is something particular to your models, your configuration, or possibly even the data in your database that is causing the problem you are seeing. Since you have provided no information about any of that, it's rather difficult to help diagnose. Also, this is not the right place for it. I suggest posting more information on django-users and someone may be able to help. At this point a ticket is premature because we have no idea whether the problem is in your setup or in Django itself.
I can't reproduce this error. Including the name of a
ForeignKey
field inlist_display
works just fine for me.