Commit 4412bb996e219b088ee15fbeff4ba733201c8420
1 parent
222f604e
Tests pass (Python 2.7, Django 1.5).
Showing
12 changed files
with
52 additions
and
49 deletions
| @@ -2,11 +2,12 @@ from __future__ import unicode_literals | @@ -2,11 +2,12 @@ from __future__ import unicode_literals | ||
| 2 | 2 | ||
| 3 | from django.contrib import admin | 3 | from django.contrib import admin |
| 4 | from django.contrib.auth import get_user_model | 4 | from django.contrib.auth import get_user_model |
| 5 | -from django.utils.translation import ugettext_lazy as _, ungettext, ungettext_lazy | ||
| 6 | -from django.contrib.comments.views.moderation import perform_flag, perform_approve, perform_delete | 5 | +from django.utils.translation import ugettext_lazy as _, ungettext |
| 7 | 6 | ||
| 8 | -from django_comments import get_model | ||
| 9 | from django_comments.models import Comment | 7 | from django_comments.models import Comment |
| 8 | +from django_comments import get_model | ||
| 9 | +from django_comments.views.moderation import perform_flag, perform_approve, perform_delete | ||
| 10 | + | ||
| 10 | 11 | ||
| 11 | class UsernameSearch(object): | 12 | class UsernameSearch(object): |
| 12 | """The User object may not be auth.User, so we need to provide | 13 | """The User object may not be auth.User, so we need to provide |
| @@ -43,7 +44,7 @@ class CommentsAdmin(admin.ModelAdmin): | @@ -43,7 +44,7 @@ class CommentsAdmin(admin.ModelAdmin): | ||
| 43 | # Only superusers should be able to delete the comments from the DB. | 44 | # Only superusers should be able to delete the comments from the DB. |
| 44 | if not request.user.is_superuser and 'delete_selected' in actions: | 45 | if not request.user.is_superuser and 'delete_selected' in actions: |
| 45 | actions.pop('delete_selected') | 46 | actions.pop('delete_selected') |
| 46 | - if not request.user.has_perm('comments.can_moderate'): | 47 | + if not request.user.has_perm('django_comments.can_moderate'): |
| 47 | if 'approve_comments' in actions: | 48 | if 'approve_comments' in actions: |
| 48 | actions.pop('approve_comments') | 49 | actions.pop('approve_comments') |
| 49 | if 'remove_comments' in actions: | 50 | if 'remove_comments' in actions: |
| @@ -52,20 +53,17 @@ class CommentsAdmin(admin.ModelAdmin): | @@ -52,20 +53,17 @@ class CommentsAdmin(admin.ModelAdmin): | ||
| 52 | 53 | ||
| 53 | def flag_comments(self, request, queryset): | 54 | def flag_comments(self, request, queryset): |
| 54 | self._bulk_flag(request, queryset, perform_flag, | 55 | self._bulk_flag(request, queryset, perform_flag, |
| 55 | - ungettext_lazy('%d comment was successfully flagged', | ||
| 56 | - '%d comments were successfully flagged')) | 56 | + lambda n: ungettext('flagged', 'flagged', n)) |
| 57 | flag_comments.short_description = _("Flag selected comments") | 57 | flag_comments.short_description = _("Flag selected comments") |
| 58 | 58 | ||
| 59 | def approve_comments(self, request, queryset): | 59 | def approve_comments(self, request, queryset): |
| 60 | self._bulk_flag(request, queryset, perform_approve, | 60 | self._bulk_flag(request, queryset, perform_approve, |
| 61 | - ungettext_lazy('%d comment was successfully approved', | ||
| 62 | - '%d comments were successfully approved')) | 61 | + lambda n: ungettext('approved', 'approved', n)) |
| 63 | approve_comments.short_description = _("Approve selected comments") | 62 | approve_comments.short_description = _("Approve selected comments") |
| 64 | 63 | ||
| 65 | def remove_comments(self, request, queryset): | 64 | def remove_comments(self, request, queryset): |
| 66 | self._bulk_flag(request, queryset, perform_delete, | 65 | self._bulk_flag(request, queryset, perform_delete, |
| 67 | - ungettext_lazy('%d comment was successfully removed', | ||
| 68 | - '%d comments were successfully removed')) | 66 | + lambda n: ungettext('removed', 'removed', n)) |
| 69 | remove_comments.short_description = _("Remove selected comments") | 67 | remove_comments.short_description = _("Remove selected comments") |
| 70 | 68 | ||
| 71 | def _bulk_flag(self, request, queryset, action, done_message): | 69 | def _bulk_flag(self, request, queryset, action, done_message): |
| @@ -78,7 +76,10 @@ class CommentsAdmin(admin.ModelAdmin): | @@ -78,7 +76,10 @@ class CommentsAdmin(admin.ModelAdmin): | ||
| 78 | action(request, comment) | 76 | action(request, comment) |
| 79 | n_comments += 1 | 77 | n_comments += 1 |
| 80 | 78 | ||
| 81 | - self.message_user(request, done_message % n_comments) | 79 | + msg = ungettext('1 comment was successfully %(action)s.', |
| 80 | + '%(count)s comments were successfully %(action)s.', | ||
| 81 | + n_comments) | ||
| 82 | + self.message_user(request, msg % {'count': n_comments, 'action': done_message(n_comments)}) | ||
| 82 | 83 | ||
| 83 | # Only register the default admin if the model is the built-in comment model | 84 | # Only register the default admin if the model is the built-in comment model |
| 84 | # (this won't be true if there's a custom comment app). | 85 | # (this won't be true if there's a custom comment app). |
| @@ -8,7 +8,7 @@ class CommentManager(models.Manager): | @@ -8,7 +8,7 @@ class CommentManager(models.Manager): | ||
| 8 | """ | 8 | """ |
| 9 | QuerySet for all comments currently in the moderation queue. | 9 | QuerySet for all comments currently in the moderation queue. |
| 10 | """ | 10 | """ |
| 11 | - return self.get_queryset().filter(is_public=False, is_removed=False) | 11 | + return self.get_query_set().filter(is_public=False, is_removed=False) |
| 12 | 12 | ||
| 13 | def for_model(self, model): | 13 | def for_model(self, model): |
| 14 | """ | 14 | """ |
| @@ -16,7 +16,7 @@ class CommentManager(models.Manager): | @@ -16,7 +16,7 @@ class CommentManager(models.Manager): | ||
| 16 | a class). | 16 | a class). |
| 17 | """ | 17 | """ |
| 18 | ct = ContentType.objects.get_for_model(model) | 18 | ct = ContentType.objects.get_for_model(model) |
| 19 | - qs = self.get_queryset().filter(content_type=ct) | 19 | + qs = self.get_query_set().filter(content_type=ct) |
| 20 | if isinstance(model, models.Model): | 20 | if isinstance(model, models.Model): |
| 21 | qs = qs.filter(object_pk=force_text(model._get_pk_val())) | 21 | qs = qs.filter(object_pk=force_text(model._get_pk_val())) |
| 22 | return qs | 22 | return qs |
| @@ -303,7 +303,7 @@ class Moderator(object): | @@ -303,7 +303,7 @@ class Moderator(object): | ||
| 303 | model_or_iterable = [model_or_iterable] | 303 | model_or_iterable = [model_or_iterable] |
| 304 | for model in model_or_iterable: | 304 | for model in model_or_iterable: |
| 305 | if model in self._registry: | 305 | if model in self._registry: |
| 306 | - raise AlreadyModerated("The model '%s' is already being moderated" % model._meta.model_name) | 306 | + raise AlreadyModerated("The model '%s' is already being moderated" % model._meta.module_name) |
| 307 | self._registry[model] = moderation_class(model) | 307 | self._registry[model] = moderation_class(model) |
| 308 | 308 | ||
| 309 | def unregister(self, model_or_iterable): | 309 | def unregister(self, model_or_iterable): |
| @@ -319,7 +319,7 @@ class Moderator(object): | @@ -319,7 +319,7 @@ class Moderator(object): | ||
| 319 | model_or_iterable = [model_or_iterable] | 319 | model_or_iterable = [model_or_iterable] |
| 320 | for model in model_or_iterable: | 320 | for model in model_or_iterable: |
| 321 | if model not in self._registry: | 321 | if model not in self._registry: |
| 322 | - raise NotModerated("The model '%s' is not currently being moderated" % model._meta.model_name) | 322 | + raise NotModerated("The model '%s' is not currently being moderated" % model._meta.module_name) |
| 323 | del self._registry[model] | 323 | del self._registry[model] |
| 324 | 324 | ||
| 325 | def pre_save_moderation(self, sender, comment, request, **kwargs): | 325 | def pre_save_moderation(self, sender, comment, request, **kwargs): |
| @@ -2,8 +2,6 @@ from django import template | @@ -2,8 +2,6 @@ from django import template | ||
| 2 | from django.template.loader import render_to_string | 2 | from django.template.loader import render_to_string |
| 3 | from django.conf import settings | 3 | from django.conf import settings |
| 4 | from django.contrib.contenttypes.models import ContentType | 4 | from django.contrib.contenttypes.models import ContentType |
| 5 | -from django.utils import six | ||
| 6 | -from django.utils.deprecation import RenameMethodsBase | ||
| 7 | from django.utils.encoding import smart_text | 5 | from django.utils.encoding import smart_text |
| 8 | 6 | ||
| 9 | import django_comments | 7 | import django_comments |
| @@ -11,13 +9,7 @@ import django_comments | @@ -11,13 +9,7 @@ import django_comments | ||
| 11 | register = template.Library() | 9 | register = template.Library() |
| 12 | 10 | ||
| 13 | 11 | ||
| 14 | -class RenameBaseCommentNodeMethods(RenameMethodsBase): | ||
| 15 | - renamed_methods = ( | ||
| 16 | - ('get_query_set', 'get_queryset', PendingDeprecationWarning), | ||
| 17 | - ) | ||
| 18 | - | ||
| 19 | - | ||
| 20 | -class BaseCommentNode(six.with_metaclass(RenameBaseCommentNodeMethods, template.Node)): | 12 | +class BaseCommentNode(template.Node): |
| 21 | """ | 13 | """ |
| 22 | Base helper class (abstract) for handling the get_comment_* template tags. | 14 | Base helper class (abstract) for handling the get_comment_* template tags. |
| 23 | Looks a bit strange, but the subclasses below should make this a bit more | 15 | Looks a bit strange, but the subclasses below should make this a bit more |
| @@ -74,11 +66,11 @@ class BaseCommentNode(six.with_metaclass(RenameBaseCommentNodeMethods, template. | @@ -74,11 +66,11 @@ class BaseCommentNode(six.with_metaclass(RenameBaseCommentNodeMethods, template. | ||
| 74 | self.comment = comment | 66 | self.comment = comment |
| 75 | 67 | ||
| 76 | def render(self, context): | 68 | def render(self, context): |
| 77 | - qs = self.get_queryset(context) | 69 | + qs = self.get_query_set(context) |
| 78 | context[self.as_varname] = self.get_context_value_from_queryset(context, qs) | 70 | context[self.as_varname] = self.get_context_value_from_queryset(context, qs) |
| 79 | return '' | 71 | return '' |
| 80 | 72 | ||
| 81 | - def get_queryset(self, context): | 73 | + def get_query_set(self, context): |
| 82 | ctype, object_pk = self.get_target_ctype_pk(context) | 74 | ctype, object_pk = self.get_target_ctype_pk(context) |
| 83 | if not object_pk: | 75 | if not object_pk: |
| 84 | return self.comment_model.objects.none() | 76 | return self.comment_model.objects.none() |
| @@ -215,7 +207,7 @@ class RenderCommentListNode(CommentListNode): | @@ -215,7 +207,7 @@ class RenderCommentListNode(CommentListNode): | ||
| 215 | "comments/%s/list.html" % ctype.app_label, | 207 | "comments/%s/list.html" % ctype.app_label, |
| 216 | "comments/list.html" | 208 | "comments/list.html" |
| 217 | ] | 209 | ] |
| 218 | - qs = self.get_queryset(context) | 210 | + qs = self.get_query_set(context) |
| 219 | context.push() | 211 | context.push() |
| 220 | liststr = render_to_string(template_search_list, { | 212 | liststr = render_to_string(template_search_list, { |
| 221 | "comment_list" : self.get_context_value_from_queryset(context, qs) | 213 | "comment_list" : self.get_context_value_from_queryset(context, qs) |
| @@ -86,10 +86,10 @@ def post_comment(request, next=None, using=None): | @@ -86,10 +86,10 @@ def post_comment(request, next=None, using=None): | ||
| 86 | # These first two exist for purely historical reasons. | 86 | # These first two exist for purely historical reasons. |
| 87 | # Django v1.0 and v1.1 allowed the underscore format for | 87 | # Django v1.0 and v1.1 allowed the underscore format for |
| 88 | # preview templates, so we have to preserve that format. | 88 | # preview templates, so we have to preserve that format. |
| 89 | - "comments/%s_%s_preview.html" % (model._meta.app_label, model._meta.model_name), | 89 | + "comments/%s_%s_preview.html" % (model._meta.app_label, model._meta.module_name), |
| 90 | "comments/%s_preview.html" % model._meta.app_label, | 90 | "comments/%s_preview.html" % model._meta.app_label, |
| 91 | # Now the usual directory based template hierarchy. | 91 | # Now the usual directory based template hierarchy. |
| 92 | - "comments/%s/%s/preview.html" % (model._meta.app_label, model._meta.model_name), | 92 | + "comments/%s/%s/preview.html" % (model._meta.app_label, model._meta.module_name), |
| 93 | "comments/%s/preview.html" % model._meta.app_label, | 93 | "comments/%s/preview.html" % model._meta.app_label, |
| 94 | "comments/preview.html", | 94 | "comments/preview.html", |
| 95 | ] | 95 | ] |
| @@ -37,7 +37,7 @@ def flag(request, comment_id, next=None): | @@ -37,7 +37,7 @@ def flag(request, comment_id, next=None): | ||
| 37 | ) | 37 | ) |
| 38 | 38 | ||
| 39 | @csrf_protect | 39 | @csrf_protect |
| 40 | -@permission_required("comments.can_moderate") | 40 | +@permission_required("django_comments.can_moderate") |
| 41 | def delete(request, comment_id, next=None): | 41 | def delete(request, comment_id, next=None): |
| 42 | """ | 42 | """ |
| 43 | Deletes a comment. Confirmation on GET, action on POST. Requires the "can | 43 | Deletes a comment. Confirmation on GET, action on POST. Requires the "can |
| @@ -65,7 +65,7 @@ def delete(request, comment_id, next=None): | @@ -65,7 +65,7 @@ def delete(request, comment_id, next=None): | ||
| 65 | ) | 65 | ) |
| 66 | 66 | ||
| 67 | @csrf_protect | 67 | @csrf_protect |
| 68 | -@permission_required("comments.can_moderate") | 68 | +@permission_required("django_comments.can_moderate") |
| 69 | def approve(request, comment_id, next=None): | 69 | def approve(request, comment_id, next=None): |
| 70 | """ | 70 | """ |
| 71 | Approve a comment (that is, mark it as public and non-removed). Confirmation | 71 | Approve a comment (that is, mark it as public and non-removed). Confirmation |
| @@ -17,6 +17,7 @@ settings.configure( | @@ -17,6 +17,7 @@ settings.configure( | ||
| 17 | INSTALLED_APPS = [ | 17 | INSTALLED_APPS = [ |
| 18 | "django.contrib.auth", | 18 | "django.contrib.auth", |
| 19 | "django.contrib.contenttypes", | 19 | "django.contrib.contenttypes", |
| 20 | + "django.contrib.sessions", | ||
| 20 | "django.contrib.sites", | 21 | "django.contrib.sites", |
| 21 | "django.contrib.admin", | 22 | "django.contrib.admin", |
| 22 | "django_comments", | 23 | "django_comments", |
| @@ -31,8 +32,8 @@ settings.configure( | @@ -31,8 +32,8 @@ settings.configure( | ||
| 31 | from django.test.simple import DjangoTestSuiteRunner | 32 | from django.test.simple import DjangoTestSuiteRunner |
| 32 | 33 | ||
| 33 | def main(): | 34 | def main(): |
| 34 | - runner = DjangoTestSuiteRunner() | ||
| 35 | - failures = runner.run_tests(['testapp'], verbosity=1, interactive=True) | 35 | + runner = DjangoTestSuiteRunner(failfast=True, verbosity=1) |
| 36 | + failures = runner.run_tests(['testapp'], interactive=True) | ||
| 36 | sys.exit(failures) | 37 | sys.exit(failures) |
| 37 | 38 | ||
| 38 | if __name__ == '__main__': | 39 | if __name__ == '__main__': |
| @@ -94,3 +94,4 @@ from .templatetag_tests import * | @@ -94,3 +94,4 @@ from .templatetag_tests import * | ||
| 94 | from .comment_view_tests import * | 94 | from .comment_view_tests import * |
| 95 | from .moderation_view_tests import * | 95 | from .moderation_view_tests import * |
| 96 | from .comment_utils_moderators_tests import * | 96 | from .comment_utils_moderators_tests import * |
| 97 | + |
| 1 | from __future__ import absolute_import | 1 | from __future__ import absolute_import |
| 2 | 2 | ||
| 3 | from django.core import mail | 3 | from django.core import mail |
| 4 | +from django.test.utils import override_settings | ||
| 4 | 5 | ||
| 5 | from django_comments.models import Comment | 6 | from django_comments.models import Comment |
| 6 | from django_comments.moderation import (moderator, CommentModerator, | 7 | from django_comments.moderation import (moderator, CommentModerator, |
| @@ -68,9 +69,10 @@ class CommentUtilsModeratorTests(CommentTestCase): | @@ -68,9 +69,10 @@ class CommentUtilsModeratorTests(CommentTestCase): | ||
| 68 | self.assertRaises(AlreadyModerated, moderator.register, Entry, EntryModerator1) | 69 | self.assertRaises(AlreadyModerated, moderator.register, Entry, EntryModerator1) |
| 69 | 70 | ||
| 70 | def testEmailNotification(self): | 71 | def testEmailNotification(self): |
| 71 | - moderator.register(Entry, EntryModerator1) | ||
| 72 | - self.createSomeComments() | ||
| 73 | - self.assertEqual(len(mail.outbox), 2) | 72 | + with override_settings(MANAGERS=("test@example.com",)): |
| 73 | + moderator.register(Entry, EntryModerator1) | ||
| 74 | + self.createSomeComments() | ||
| 75 | + self.assertEqual(len(mail.outbox), 2) | ||
| 74 | 76 | ||
| 75 | def testCommentsEnabled(self): | 77 | def testCommentsEnabled(self): |
| 76 | moderator.register(Entry, EntryModerator2) | 78 | moderator.register(Entry, EntryModerator2) |
| @@ -262,7 +262,7 @@ class AdminActionsTests(CommentTestCase): | @@ -262,7 +262,7 @@ class AdminActionsTests(CommentTestCase): | ||
| 262 | u = User.objects.get(username="normaluser") | 262 | u = User.objects.get(username="normaluser") |
| 263 | u.is_staff = True | 263 | u.is_staff = True |
| 264 | perms = Permission.objects.filter( | 264 | perms = Permission.objects.filter( |
| 265 | - content_type__app_label = 'comments', | 265 | + content_type__app_label = 'django_comments', |
| 266 | codename__endswith = 'comment' | 266 | codename__endswith = 'comment' |
| 267 | ) | 267 | ) |
| 268 | for perm in perms: | 268 | for perm in perms: |
| @@ -272,31 +272,34 @@ class AdminActionsTests(CommentTestCase): | @@ -272,31 +272,34 @@ class AdminActionsTests(CommentTestCase): | ||
| 272 | def testActionsNonModerator(self): | 272 | def testActionsNonModerator(self): |
| 273 | comments = self.createSomeComments() | 273 | comments = self.createSomeComments() |
| 274 | self.client.login(username="normaluser", password="normaluser") | 274 | self.client.login(username="normaluser", password="normaluser") |
| 275 | - response = self.client.get("/admin/comments/comment/") | 275 | + response = self.client.get("/admin/django_comments/comment/") |
| 276 | self.assertNotContains(response, "approve_comments") | 276 | self.assertNotContains(response, "approve_comments") |
| 277 | 277 | ||
| 278 | def testActionsModerator(self): | 278 | def testActionsModerator(self): |
| 279 | comments = self.createSomeComments() | 279 | comments = self.createSomeComments() |
| 280 | makeModerator("normaluser") | 280 | makeModerator("normaluser") |
| 281 | self.client.login(username="normaluser", password="normaluser") | 281 | self.client.login(username="normaluser", password="normaluser") |
| 282 | - response = self.client.get("/admin/comments/comment/") | 282 | + response = self.client.get("/admin/django_comments/comment/") |
| 283 | self.assertContains(response, "approve_comments") | 283 | self.assertContains(response, "approve_comments") |
| 284 | 284 | ||
| 285 | def testActionsDisabledDelete(self): | 285 | def testActionsDisabledDelete(self): |
| 286 | "Tests a CommentAdmin where 'delete_selected' has been disabled." | 286 | "Tests a CommentAdmin where 'delete_selected' has been disabled." |
| 287 | comments = self.createSomeComments() | 287 | comments = self.createSomeComments() |
| 288 | self.client.login(username="normaluser", password="normaluser") | 288 | self.client.login(username="normaluser", password="normaluser") |
| 289 | - response = self.client.get('/admin2/comments/comment/') | 289 | + response = self.client.get('/admin2/django_comments/comment/') |
| 290 | self.assertEqual(response.status_code, 200) | 290 | self.assertEqual(response.status_code, 200) |
| 291 | self.assertNotContains(response, '<option value="delete_selected">') | 291 | self.assertNotContains(response, '<option value="delete_selected">') |
| 292 | 292 | ||
| 293 | def performActionAndCheckMessage(self, action, action_params, expected_message): | 293 | def performActionAndCheckMessage(self, action, action_params, expected_message): |
| 294 | - response = self.client.post('/admin/comments/comment/', | 294 | + response = self.client.post('/admin/django_comments/comment/', |
| 295 | data={'_selected_action': action_params, | 295 | data={'_selected_action': action_params, |
| 296 | 'action': action, | 296 | 'action': action, |
| 297 | 'index': 0}, | 297 | 'index': 0}, |
| 298 | follow=True) | 298 | follow=True) |
| 299 | - self.assertContains(response, expected_message) | 299 | + messages = list(m.message for m in response.context['messages']) |
| 300 | + self.assert_(expected_message in messages, | ||
| 301 | + ("Expected message '%s' wasn't set (messages were: %s)" % | ||
| 302 | + (expected_message, messages))) | ||
| 300 | 303 | ||
| 301 | def testActionsMessageTranslations(self): | 304 | def testActionsMessageTranslations(self): |
| 302 | c1, c2, c3, c4 = self.createSomeComments() | 305 | c1, c2, c3, c4 = self.createSomeComments() |
| @@ -306,11 +309,11 @@ class AdminActionsTests(CommentTestCase): | @@ -306,11 +309,11 @@ class AdminActionsTests(CommentTestCase): | ||
| 306 | self.client.login(username="normaluser", password="normaluser") | 309 | self.client.login(username="normaluser", password="normaluser") |
| 307 | with translation.override('en'): | 310 | with translation.override('en'): |
| 308 | #Test approving | 311 | #Test approving |
| 309 | - self.performActionAndCheckMessage('approve_comments', one_comment, '1 comment was successfully approved') | ||
| 310 | - self.performActionAndCheckMessage('approve_comments', many_comments, '3 comments were successfully approved') | 312 | + self.performActionAndCheckMessage('approve_comments', one_comment, '1 comment was successfully approved.') |
| 313 | + self.performActionAndCheckMessage('approve_comments', many_comments, '3 comments were successfully approved.') | ||
| 311 | #Test flagging | 314 | #Test flagging |
| 312 | - self.performActionAndCheckMessage('flag_comments', one_comment, '1 comment was successfully flagged') | ||
| 313 | - self.performActionAndCheckMessage('flag_comments', many_comments, '3 comments were successfully flagged') | 315 | + self.performActionAndCheckMessage('flag_comments', one_comment, '1 comment was successfully flagged.') |
| 316 | + self.performActionAndCheckMessage('flag_comments', many_comments, '3 comments were successfully flagged.') | ||
| 314 | #Test removing | 317 | #Test removing |
| 315 | - self.performActionAndCheckMessage('remove_comments', one_comment, '1 comment was successfully removed') | ||
| 316 | - self.performActionAndCheckMessage('remove_comments', many_comments, '3 comments were successfully removed') | 318 | + self.performActionAndCheckMessage('remove_comments', one_comment, '1 comment was successfully removed.') |
| 319 | + self.performActionAndCheckMessage('remove_comments', many_comments, '3 comments were successfully removed.') |
| @@ -4,7 +4,7 @@ from django.conf.urls import patterns, url | @@ -4,7 +4,7 @@ from django.conf.urls import patterns, url | ||
| 4 | 4 | ||
| 5 | from django_comments.feeds import LatestCommentFeed | 5 | from django_comments.feeds import LatestCommentFeed |
| 6 | 6 | ||
| 7 | -from .custom_comments import views | 7 | +from custom_comments import views |
| 8 | 8 | ||
| 9 | 9 | ||
| 10 | feeds = { | 10 | feeds = { |
Please
register
or
login
to post a comment