I am getting a FieldError when I try to edit certain models in the Django admin.
As far as I can tell, this started happening after I started using .annotate()
in some of my ModelAdmin
classes. The error shows up if I try to edit a Profile or a Photo. It also shows up if I try to edit a token (I am using Django REST Framework). What's confusing me though is why Token is also breaking; I have't touched that model at all. Here are the relevant models:
class User(AbstractBaseUser, common_models.EditMixin, PermissionsMixin):
age = models.PositiveSmallIntegerField(blank=True, null=True)
avatar = models.ImageField(upload_to=common_models.get_uploaded_file_path, blank=True, null=True)
email = models.EmailField(max_length=255, unique=True)
first_name = models.CharField(max_length=64, blank=True, null=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False, verbose_name='staff account')
last_name = models.CharField(max_length=64, blank=True, null=True)
username = models.CharField(max_length=255, unique=True)
USERNAME_FIELD = 'email'
class Profile(models.Model):
user = models.ForeignKey(User)
bio = models.TextField(blank=True, null=True)
cover_image = models.ImageField(upload_to=common_models.get_uploaded_file_path, blank=True, null=True)
gear = models.TextField(blank=True, null=True)
class UserAction(models.Model):
ACTION_CHOICES = (
('photo_click', 'Photo Click'),
('photo_imp', 'Photo Impression'),
)
user = models.ForeignKey(account_models.User)
action = models.CharField(max_length=32, choices=ACTION_CHOICES)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
class PhotoClassification(models.Model):
CLASSIFICATION_TYPE_CHOICES = (
('category', 'Category'),
('tag', 'Tag')
)
classification_type = models.CharField(max_length=32, choices=CLASSIFICATION_TYPE_CHOICES, default='tag')
name = models.CharField(max_length=64)
public = models.BooleanField(default=True)
class PhotoFeed(models.Model):
name = models.CharField(max_length=64)
public = models.BooleanField(default=True)
class Photo(common_models.EditMixin):
category = models.ManyToManyField(PhotoClassification, related_name='category')
photo_feed = models.ManyToManyField(PhotoFeed, blank=True)
tag = models.ManyToManyField(PhotoClassification, blank=True, related_name='tag')
user = models.ForeignKey(account_models.User, blank=True, null=True)
user_action = GenericRelation(UserAction)
attribution_name = models.CharField(max_length=255, blank=True, null=True)
image = models.ImageField(upload_to=common_models.get_uploaded_file_path)
public = models.BooleanField(default=True)
Here is one of the ModelAdmin
classes that user .annotate()
:
class PhotoClassificationAdmin(admin.ModelAdmin):
"""
Categories and tags
"""
list_display = ('name', 'classification_type', 'photo_count', 'public', 'id',)
ordering = ('classification_type', 'name',)
search_fields = ('name', 'classification_type', 'id',)
def get_queryset(self, request):
return super(PhotoClassificationAdmin, self).get_queryset(request)\
.annotate(photos_in_category=Count('category'), photos_in_tag=Count('tag'))
def photo_count(self, obj):
return obj.photos_in_category + obj.photos_in_tag
photo_count.admin_order_field = 'photos'
photo_count.short_description = 'Photos'
Here's the stack trace:
Internal Server Error: /admin/photo/photo/120/change/
Traceback (most recent call last):
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/core/handlers/exception.py", line 39, in inner
response = get_response(request)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/core/handlers/base.py", line 217, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/core/handlers/base.py", line 215, in _get_response
response = response.render()
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/response.py", line 109, in render
self.content = self.rendered_content
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/response.py", line 86, in rendered_content
content = template.render(context, self._request)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/backends/django.py", line 66, in render
return self.template.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 208, in render
return self._render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 199, in _render
return self.nodelist.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 994, in render
bit = node.render_annotated(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/loader_tags.py", line 174, in render
return compiled_parent._render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 199, in _render
return self.nodelist.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 994, in render
bit = node.render_annotated(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/loader_tags.py", line 174, in render
return compiled_parent._render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 199, in _render
return self.nodelist.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 994, in render
bit = node.render_annotated(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/loader_tags.py", line 70, in render
result = block.nodelist.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 994, in render
bit = node.render_annotated(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/loader_tags.py", line 70, in render
result = block.nodelist.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 994, in render
bit = node.render_annotated(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/loader_tags.py", line 70, in render
result = block.nodelist.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 994, in render
bit = node.render_annotated(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/defaulttags.py", line 209, in render
nodelist.append(node.render_annotated(context))
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/loader_tags.py", line 210, in render
return template.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 210, in render
return self._render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 199, in _render
return self.nodelist.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 994, in render
bit = node.render_annotated(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/defaulttags.py", line 209, in render
nodelist.append(node.render_annotated(context))
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/defaulttags.py", line 209, in render
nodelist.append(node.render_annotated(context))
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/defaulttags.py", line 315, in render
return nodelist.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 994, in render
bit = node.render_annotated(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/defaulttags.py", line 315, in render
return nodelist.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 994, in render
bit = node.render_annotated(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 961, in render_annotated
return self.render(context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 1050, in render
return render_value_in_context(output, context)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/template/base.py", line 1028, in render_value_in_context
value = force_text(value)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/utils/encoding.py", line 76, in force_text
s = six.text_type(s)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/utils/html.py", line 391, in <lambda>
klass.__str__ = lambda self: mark_safe(klass_str(self))
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/forms/boundfield.py", line 43, in __str__
return self.as_widget()
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/forms/boundfield.py", line 101, in as_widget
return force_text(widget.render(name, self.value(), attrs=attrs))
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/contrib/admin/widgets.py", line 307, in render
'widget': self.widget.render(name, value, *args, **kwargs),
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/forms/widgets.py", line 544, in render
options = self.render_options([value])
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/forms/widgets.py", line 567, in render_options
for option_value, option_label in self.choices:
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/forms/models.py", line 1118, in __iter__
for obj in queryset:
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/db/models/query.py", line 54, in __iter__
results = compiler.execute_sql()
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 824, in execute_sql
sql, params = self.as_sql()
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 369, in as_sql
extra_select, order_by, group_by = self.pre_sql_setup()
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 47, in pre_sql_setup
order_by = self.get_order_by()
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 293, in get_order_by
field, self.query.get_meta(), default_order=asc))
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 553, in find_ordering_name
field, targets, alias, joins, path, opts = self._setup_joins(pieces, opts, alias)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 586, in _setup_joins
pieces, opts, alias)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/db/models/sql/query.py", line 1402, in setup_joins
names, opts, allow_many, fail_on_missing=True)
File "/home/martin/projects/aov3.5/lib/python3.5/site-packages/django/db/models/sql/query.py", line 1327, in names_to_path
"Choices are: %s" % (name, ", ".join(available)))
django.core.exceptions.FieldError: Cannot resolve keyword 'count' into field. Choices are: attribution_name, category, created_at, id, image, location, modified_at, original_image_url, photo_data, photo_feed, public, tag, user, user_action, user_id