2012-03-30 9 views
4

Ich weiß in Vorlagen können Sie problemlos Kommentare mit get_comment_count zählen, aber wie erhalten Sie die gleiche Anzahl als eine Methode in einer Klasse in models.py?Zählen Kommentare pro Objekt in `models.py` mit Django Kommentare Framework

Zum Beispiel

Ich mag comment_count haben, so dass ich ein die Kommentare in der Admin-Seite zählen zu bekommen.

EDIT: Für Ihre Bequemlichkeit ist hier die models.py für django.contrib.comments

from django.contrib.auth.models import User 
from django.contrib.comments.managers import CommentManager 
from django.contrib.contenttypes import generic 
from django.contrib.contenttypes.models import ContentType 
from django.contrib.sites.models import Site 
from django.db import models 
from django.core import urlresolvers 
from django.utils.translation import ugettext_lazy as _ 
from django.utils import timezone 
from django.conf import settings 

COMMENT_MAX_LENGTH = getattr(settings,'COMMENT_MAX_LENGTH',3000) 

class BaseCommentAbstractModel(models.Model): 
    """ 
    An abstract base class that any custom comment models probably should 
    subclass. 
    """ 

    # Content-object field 
    content_type = models.ForeignKey(ContentType, 
      verbose_name=_('content type'), 
      related_name="content_type_set_for_%(class)s") 
    object_pk  = models.TextField(_('object ID')) 
    content_object = generic.GenericForeignKey(ct_field="content_type", fk_field="object_pk") 

    # Metadata about the comment 
    site  = models.ForeignKey(Site) 

    class Meta: 
     abstract = True 

    def get_content_object_url(self): 
     """ 
     Get a URL suitable for redirecting to the content object. 
     """ 
     return urlresolvers.reverse(
      "comments-url-redirect", 
      args=(self.content_type_id, self.object_pk) 
     ) 

class Comment(BaseCommentAbstractModel): 
    """ 
    A user comment about some object. 
    """ 

    # Who posted this comment? If ``user`` is set then it was an authenticated 
    # user; otherwise at least user_name should have been set and the comment 
    # was posted by a non-authenticated user. 
    user  = models.ForeignKey(User, verbose_name=_('user'), 
        blank=True, null=True, related_name="%(class)s_comments") 
    user_name = models.CharField(_("user's name"), max_length=50, blank=True) 
    user_email = models.EmailField(_("user's email address"), blank=True) 
    user_url = models.URLField(_("user's URL"), blank=True) 

    comment = models.TextField(_('comment'), max_length=COMMENT_MAX_LENGTH) 

    # Metadata about the comment 
    submit_date = models.DateTimeField(_('date/time submitted'), default=None) 
    ip_address = models.IPAddressField(_('IP address'), blank=True, null=True) 
    is_public = models.BooleanField(_('is public'), default=True, 
        help_text=_('Uncheck this box to make the comment effectively ' \ 
           'disappear from the site.')) 
    is_removed = models.BooleanField(_('is removed'), default=False, 
        help_text=_('Check this box if the comment is inappropriate. ' \ 
           'A "This comment has been removed" message will ' \ 
           'be displayed instead.')) 

    # Manager 
    objects = CommentManager() 

    class Meta: 
     db_table = "django_comments" 
     ordering = ('submit_date',) 
     permissions = [("can_moderate", "Can moderate comments")] 
     verbose_name = _('comment') 
     verbose_name_plural = _('comments') 

    def __unicode__(self): 
     return "%s: %s..." % (self.name, self.comment[:50]) 

    def save(self, *args, **kwargs): 
     if self.submit_date is None: 
      self.submit_date = timezone.now() 
     super(Comment, self).save(*args, **kwargs) 

    def _get_userinfo(self): 
     """ 
     Get a dictionary that pulls together information about the poster 
     safely for both authenticated and non-authenticated comments. 

     This dict will have ``name``, ``email``, and ``url`` fields. 
     """ 
     if not hasattr(self, "_userinfo"): 
      self._userinfo = { 
       "name" : self.user_name, 
       "email" : self.user_email, 
       "url" : self.user_url 
      } 
      if self.user_id: 
       u = self.user 
       if u.email: 
        self._userinfo["email"] = u.email 

       # If the user has a full name, use that for the user name. 
       # However, a given user_name overrides the raw user.username, 
       # so only use that if this comment has no associated name. 
       if u.get_full_name(): 
        self._userinfo["name"] = self.user.get_full_name() 
       elif not self.user_name: 
        self._userinfo["name"] = u.username 
     return self._userinfo 
    userinfo = property(_get_userinfo, doc=_get_userinfo.__doc__) 

    def _get_name(self): 
     return self.userinfo["name"] 
    def _set_name(self, val): 
     if self.user_id: 
      raise AttributeError(_("This comment was posted by an authenticated "\ 
            "user and thus the name is read-only.")) 
     self.user_name = val 
    name = property(_get_name, _set_name, doc="The name of the user who posted this comment") 

    def _get_email(self): 
     return self.userinfo["email"] 
    def _set_email(self, val): 
     if self.user_id: 
      raise AttributeError(_("This comment was posted by an authenticated "\ 
            "user and thus the email is read-only.")) 
     self.user_email = val 
    email = property(_get_email, _set_email, doc="The email of the user who posted this comment") 

    def _get_url(self): 
     return self.userinfo["url"] 
    def _set_url(self, val): 
     self.user_url = val 
    url = property(_get_url, _set_url, doc="The URL given by the user who posted this comment") 

    def get_absolute_url(self, anchor_pattern="#c%(id)s"): 
     return self.get_content_object_url() + (anchor_pattern % self.__dict__) 

    def get_as_text(self): 
     """ 
     Return this comment as plain text. Useful for emails. 
     """ 
     d = { 
      'user': self.user or self.name, 
      'date': self.submit_date, 
      'comment': self.comment, 
      'domain': self.site.domain, 
      'url': self.get_absolute_url() 
     } 
     return _('Posted by %(user)s at %(date)s\n\n%(comment)s\n\nhttp://%(domain)s%(url)s') % d 

class CommentFlag(models.Model): 
    """ 
    Records a flag on a comment. This is intentionally flexible; right now, a 
    flag could be: 

     * A "removal suggestion" -- where a user suggests a comment for (potential) removal. 

     * A "moderator deletion" -- used when a moderator deletes a comment. 

    You can (ab)use this model to add other flags, if needed. However, by 
    design users are only allowed to flag a comment with a given flag once; 
    if you want rating look elsewhere. 
    """ 
    user  = models.ForeignKey(User, verbose_name=_('user'), related_name="comment_flags") 
    comment = models.ForeignKey(Comment, verbose_name=_('comment'), related_name="flags") 
    flag  = models.CharField(_('flag'), max_length=30, db_index=True) 
    flag_date = models.DateTimeField(_('date'), default=None) 

    # Constants for flag types 
    SUGGEST_REMOVAL = "removal suggestion" 
    MODERATOR_DELETION = "moderator deletion" 
    MODERATOR_APPROVAL = "moderator approval" 

    class Meta: 
     db_table = 'django_comment_flags' 
     unique_together = [('user', 'comment', 'flag')] 
     verbose_name = _('comment flag') 
     verbose_name_plural = _('comment flags') 

    def __unicode__(self): 
     return "%s flag of comment ID %s by %s" % \ 
      (self.flag, self.comment_id, self.user.username) 

    def save(self, *args, **kwargs): 
     if self.flag_date is None: 
      self.flag_date = timezone.now() 
     super(CommentFlag, self).save(*args, **kwargs) 

Antwort

7

Kommentare zu Ihren Models über generic relations verwandt sind, so können Sie die Kommentare für Ihr Objekt wie jedes generische Relation suchen:

from django.conrtib.comments.models import Comment 
from django.contrib.contenttypes.models import ContentType 
class Blog(models.Model) : 
    def comment_count(self) : 
     ct = ContentType.objects.get_for_model(Blog) 
     obj_pk = self.id 
     return Comment.objects.filter(content_type=ct,object_pk=obj_pk).count()