I need will create two sortable fields in Django admin by values in Though-Model.
-----------------
My models.py
----------------
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from django.db import models
from django.conf import settings
from autoslug import AutoSlugField
from mylabour.models import TimeStampedModel
from mylabour.utils import CHOICES_LEXERS
class Snippet(TimeStampedModel):
"""
"""
title = models.CharField(_('Title'), max_length=200)
slug_title = AutoSlugField(populate_from='title', unique_with='author', always_update=True, sep='__')
description = models.TextField(_('Decription'))
code = models.TextField(_('Code'))
# tags
lexer = models.CharField(_('Lexer of code'), max_length=50, choices=CHOICES_LEXERS)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name=_('Author'),
related_name='snippets',
on_delete=models.DO_NOTHING,
)
voted_users = models.ManyToManyField(
settings.AUTH_USER_MODEL,
verbose_name=_('Voted users'),
related_name='voted_users',
through='VoteUserInSnippet',
through_fields=('snippet', 'user'),
)
class Meta:
db_table = 'snippet'
verbose_name = _("Snippet")
verbose_name_plural = _("Snippets")
get_latest_by = 'date_created'
ordering = ['date_created']
def __str__(self):
return '{0.title}'.format(self)
def get_absolute_url(self):
return reverse('app_snippets:snippet', kwargs={'slug_title': self.slug_title})
class VoteUserInSnippet(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
verbose_name='User',
limit_choices_to={'is_active': True},
)
snippet = models.ForeignKey('Snippet', on_delete=models.CASCADE, verbose_name='Snippet')
is_useful = models.BooleanField(_('Is useful'))
date_voting = models.DateTimeField(_('Date voting'), auto_now_add=True)
def __str__(self):
return _('User "{0.user}" found this snippet as {0.is_useful}').format(self)
class SnippetComment(TimeStampedModel):
text_comment = models.TextField(_('Text comment'))
snippet = models.ForeignKey('Snippet', related_name='comments', verbose_name=_('Snippet'), on_delete=models.CASCADE)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
related_name='comments_snippet',
verbose_name=_('Author'),
on_delete=models.DO_NOTHING,
)
class Meta:
db_table = 'snippet_comment'
verbose_name = "Comment of snippet"
verbose_name_plural = "Comments of snippet"
get_latest_by = 'date_created'
ordering = ['snippet', 'date_created']
def __str__(self):
return _('Comment from "{0.author}" on snippet "{0.snippet}"').format(self)
-----------
My admin.py
-----------
from django.db.models import Count
from django.utils.translation import ugettext_lazy as _
from django.contrib import admin
from .models import *
class SnippetCommentInline(admin.StackedInline):
'''
Stacked Inline View for SnippetComment
'''
model = SnippetComment
min_num = 0
max_num = None
extra = 1
fk_name = 'snippet'
class VoteUserInSnippetInline(admin.TabularInline):
'''
Stacked Inline View for VoteUserInSnippet
'''
model = VoteUserInSnippet
min_num = 0
max_num = None
extra = 1
class SnippetAdmin(admin.ModelAdmin):
'''
Admin View for Snippet
'''
list_display = (
'title',
'author',
'lexer',
'get_count_good_reply',
'get_count_bad_reply',
'get_count_replies',
'is_new',
'date_modified',
'date_created',
)
list_filter = (
('author', admin.RelatedOnlyFieldListFilter),
'lexer',
'date_modified',
'date_created',
)
inlines = [
SnippetCommentInline,
VoteUserInSnippetInline,
]
search_fields = ('title',)
def get_queryset(self, request):
qs = super(SnippetAdmin, self).get_queryset(request)
qs = qs.annotate(
count_comments=Count('comments', distinct=True),
count_voted_users=Count('voted_users', distinct=True),
)
return qs
def get_count_comments(self, obj):
return obj.count_comments
get_count_comments.admin_order_field = 'count_comments'
get_count_comments.short_order = _('Count comments')
def get_count_good_replies(self, obj):
return VoteUserInSnippet.objects.filter(snippet=obj, is_useful=True).count()
# get_count_good_replies.admin_order_field = ''
get_count_good_replies.short_order = _('Count good replies')
def get_count_bad_replies(self, obj):
return VoteUserInSnippet.objects.filter(snippet=obj, is_useful=False).count()
# get_count_bad_replies.admin_order_field = ''
get_count_bad_replies.short_order = _('Count bad replies')
def get_count_replies(self, obj):
return obj.count_voted_users
get_count_replies.admin_order_field = 'count_voted_users'
get_count_replies.short_order = _('Count replies')
class VoteUserInSnippetAdmin(admin.ModelAdmin):
'''
Admin View for VoteUserInSnippet
'''
list_display = ('snippet', 'user', 'is_useful', 'date_voting')
list_filter = (
('user', admin.RelatedOnlyFieldListFilter),
('snippet', admin.RelatedOnlyFieldListFilter),
'is_useful',
'date_voting',
)
class SnippetCommentAdmin(admin.ModelAdmin):
'''
Admin View for SnippetComment
'''
list_display = ('snippet', 'author', 'is_new', 'date_modified', 'date_created')
list_filter = (
('author', admin.RelatedOnlyFieldListFilter),
('snippet', admin.RelatedOnlyFieldListFilter),
'date_modified',
'date_created',
)
Methods get_count_bad_replies() and get_count_bad_replies() right worked but is not sortable.
May be who known have resolve this problem.
Thanks.
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/140f0b6b-2985-4a32-abc9-762edc199931%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.