Switch to using ModelForm for CommentForm. Move comment posting code from many places to utils.py (post_comment).

portnov [2008-06-17 08:52:47]
Switch to using ModelForm for CommentForm. Move comment posting code from many places to utils.py (post_comment).
Filename
locale/ru/LC_MESSAGES/django.mo
locale/ru/LC_MESSAGES/django.po
mgmt/bugs_views.py
mgmt/documents_views.py
mgmt/forms.py
mgmt/models.py
mgmt/project_views.py
mgmt/requests_views.py
mgmt/utils.py
diff --git a/locale/ru/LC_MESSAGES/django.mo b/locale/ru/LC_MESSAGES/django.mo
index ed9da2b..ea779fd 100644
Binary files a/locale/ru/LC_MESSAGES/django.mo and b/locale/ru/LC_MESSAGES/django.mo differ
diff --git a/locale/ru/LC_MESSAGES/django.po b/locale/ru/LC_MESSAGES/django.po
index 6c7cd70..c5fd360 100644
--- a/locale/ru/LC_MESSAGES/django.po
+++ b/locale/ru/LC_MESSAGES/django.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Django\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-06-17 13:53+0600\n"
+"POT-Creation-Date: 2008-06-17 14:04+0600\n"
 "PO-Revision-Date: 2006-09-07 15:28+0300\n"
 "Last-Translator: Vasiliy Stavenko <stavenko@gmail.com>\n"
 "Language-Team: Dialcom Services <greg@dial.com.ru>\n"
@@ -19,11 +19,11 @@ msgstr ""
 "X-Poedit-Country: RUSSIAN FEDERATION\n"
 "X-Poedit-SourceCharset: utf-8\n"

-#: mgmt/models.py:12
+#: mgmt/models.py:12 mgmt/models.py:100
 msgid "Name"
 msgstr "Название"

-#: mgmt/models.py:13
+#: mgmt/models.py:13 mgmt/models.py:128
 msgid "Text"
 msgstr "Текст"

@@ -51,7 +51,7 @@ msgstr "Команда"
 msgid "Is open"
 msgstr "Открытый"

-#: mgmt/models.py:29 mgmt/models.py:47 mgmt/models.py:66
+#: mgmt/models.py:29 mgmt/models.py:47 mgmt/models.py:66 mgmt/models.py:113
 msgid "Project"
 msgstr "Проект"

@@ -67,7 +67,8 @@ msgstr "Состояние бага"
 msgid "Bug states"
 msgstr "Состояния багов"

-#: mgmt/models.py:48 mgmt/models.py:76
+#: mgmt/models.py:48 mgmt/models.py:76 mgmt/models.py:90 mgmt/models.py:114
+#: mgmt/models.py:139
 msgid "Author"
 msgstr "Автор"

@@ -79,14 +80,13 @@ msgstr "Подтвердил"
 msgid "Responsible"
 msgstr "Ответственный"

-#: mgmt/models.py:51 mgmt/models.py:67
+#: mgmt/models.py:51 mgmt/models.py:67 mgmt/models.py:81
 msgid "Status"
 msgstr "Состояние"

 #: mgmt/models.py:52
-#, fuzzy
 msgid "Component"
-msgstr "Комментарий"
+msgstr "Компонент"

 #: mgmt/models.py:53
 msgid "Your actions"
@@ -108,7 +108,7 @@ msgstr "Приоритет"
 msgid "Complexity"
 msgstr "Сложность"

-#: mgmt/models.py:59
+#: mgmt/models.py:59 mgmt/models.py:79
 msgid "Bug"
 msgstr "Баг"

@@ -116,7 +116,7 @@ msgstr "Баг"
 msgid "Bugs"
 msgstr "Баги"

-#: mgmt/models.py:69
+#: mgmt/models.py:69 mgmt/models.py:80
 msgid "Feature request"
 msgstr "Запрос функционала"

@@ -124,11 +124,11 @@ msgstr "Запрос функционала"
 msgid "Feature requests"
 msgstr "Запросы функционала"

-#: mgmt/models.py:77
+#: mgmt/models.py:77 mgmt/models.py:140
 msgid "To"
 msgstr "Кому"

-#: mgmt/models.py:83
+#: mgmt/models.py:83 mgmt/models.py:91
 msgid "Task"
 msgstr "Задание"

@@ -148,7 +148,7 @@ msgstr "Отчеты"
 msgid "Description"
 msgstr "Описание"

-#: mgmt/models.py:105
+#: mgmt/models.py:105 mgmt/models.py:112
 msgid "Category"
 msgstr "Категория"

@@ -164,6 +164,10 @@ msgstr "Документ"
 msgid "Documents"
 msgstr "Документы"

+#: mgmt/models.py:127
+msgid "Title"
+msgstr "Заголовок"
+
 #: mgmt/models.py:134
 msgid "Comment"
 msgstr "Комментарий"
diff --git a/mgmt/bugs_views.py b/mgmt/bugs_views.py
index 9443f96..3b29200 100644
--- a/mgmt/bugs_views.py
+++ b/mgmt/bugs_views.py
@@ -2,8 +2,9 @@ from django.http import HttpResponseForbidden,HttpResponseRedirect
 from django.core.urlresolvers import reverse
 from django.conf import settings
 import django.newforms as djangoforms
+from django.newforms.util import ValidationError
 from decorators import check_auth,login_required,render_to
-from utils import get_bugs,get_comments
+from utils import get_bugs,get_comments,post_comment
 from models import *
 from rights import can,possible_changes
 from forms import BugForm,BugPriorityForm,BugComplexityForm,CommentForm
@@ -33,19 +34,15 @@ def bug_report(request,pid):
 @render_to('bug.html')
 def one_bug(request,id):
   bug = Bug.objects.get(pk=id)
+  if can(request.user,'comment'):
+    form = CommentForm()
+  else:
+    form = None
   if request.method=='POST':
     if request.POST['action']=='comment':
-      title = request.POST['title']
-      text  = request.POST['text']
-      if not title:
-        title = text[:20]+'...'
-      c = Comment(created=datetime.now(),
-          author = request.user,
-          object_id = bug.id,
-          object_type = 'Bug',
-          title = title,
-          text = text)
-      c.save()
+      valid,form = post_comment(request,'Bug',bug.id, reverse('mgmt.views.one_bug',args=(bug.id,)))
+      if valid:
+        return form
     elif request.POST['action']=='change_state':
       new_state = request.POST['new_state']
       bug.status = BugState.objects.get(pk=new_state)
@@ -79,10 +76,6 @@ def one_bug(request,id):
     complexity_form = BugComplexityForm(dict(complexity=bug.complexity))
   else:
     complexity_form = None
-  if can(request.user,'comment'):
-    form = CommentForm()
-  else:
-    form = None
   if can(request.user,'edit',bug):
     edit_link = '/bugs/%s/edit/' % bug.id
   else:
diff --git a/mgmt/documents_views.py b/mgmt/documents_views.py
index e00a8d5..530aeba 100644
--- a/mgmt/documents_views.py
+++ b/mgmt/documents_views.py
@@ -1,7 +1,7 @@
 from django.http import HttpResponseRedirect
 from django.core.urlresolvers import reverse
 from decorators import check_auth,login_required,render_to
-from utils import get_comments
+from utils import get_comments,post_comment
 from models import *
 from rights import can
 from forms import CommentForm,DocForm
@@ -16,23 +16,17 @@ def project_documents(request,id):
 @render_to('document.html')
 def one_document(request,id):
   doc = Document.objects.get(pk=id)
-  if request.method=='POST':
-    title = request.POST['title']
-    text  = request.POST['text']
-    if not title:
-      title = text[:20]+'...'
-    c = Comment(created=datetime.now(),
-        author = request.user,
-        object_id = doc.id,
-        object_type = 'Document',
-        title = title,
-        text = text)
-    c.save()
-  curr,pages,comments = get_comments(request,doc.id,'Document')
   if can(request.user,'comment'):
     form = CommentForm()
   else:
     form = None
+
+  if request.method=='POST':
+    valid,form = post_comment(request,'Document',doc.id, reverse('mgmt.views.one_document',args=(doc.id,)))
+    if valid:     # Then `form' is HttpResponseRedirect
+      return form
+
+  curr,pages,comments = get_comments(request,doc.id,'Document')
   if can(request.user,'edit',doc):
     edit_link = '/docs/%s/edit/' % id
   else:
diff --git a/mgmt/forms.py b/mgmt/forms.py
index d94fa50..748ddc4 100644
--- a/mgmt/forms.py
+++ b/mgmt/forms.py
@@ -2,6 +2,7 @@
 import django.newforms as forms
 from django.contrib.auth.models import User
 from django.conf import settings
+from django.utils.translation import ugettext as _

 from models import *

@@ -9,17 +10,13 @@ from models import *
 # Forms
 ############

-class CommentForm(forms.Form):
-  title = forms.CharField(required=False)
-  text = forms.CharField(widget=forms.Textarea())
+class CommentForm(forms.ModelForm):
+  title = forms.CharField(required=False,label=_("Title"))
+  class Meta:
+    model = Comment
+    exclude = ("created","author","object_id","object_type")

 class BugForm(forms.ModelForm):
-  name = forms.CharField()
-  component = forms.CharField(required=False)
-  actions = forms.CharField(widget=forms.Textarea())
-  expected = forms.CharField(widget=forms.Textarea())
-  unexpected = forms.CharField(widget=forms.Textarea())
-  text = forms.CharField(widget=forms.Textarea())
   class Meta:
     model = Bug
     exclude = ("created","author",'project','confirmed','responsible','status','fixed','complexity','priority')
diff --git a/mgmt/models.py b/mgmt/models.py
index d6bb129..66dee16 100644
--- a/mgmt/models.py
+++ b/mgmt/models.py
@@ -76,9 +76,9 @@ class Task(Object):
   author = models.ForeignKey(User,related_name='created_tasks',verbose_name=_("Author"))
   to = models.ForeignKey(User,verbose_name=_("To"))
   project = models.ForeignKey(Project)
-  bug = models.ForeignKey(Bug,null=True)
-  request = models.ForeignKey(Request,null=True)
-  status = models.SmallIntegerField()
+  bug = models.ForeignKey(Bug,null=True,verbose_name=_("Bug"))
+  request = models.ForeignKey(Request,null=True,verbose_name=_("Feature request"))
+  status = models.SmallIntegerField(_("Status"))
   class Meta:
     verbose_name = _("Task")
     verbose_name_plural = _("Tasks")
@@ -87,8 +87,8 @@ class Task(Object):
     pass

 class Report(Object):
-  author = models.ForeignKey(User)
-  task = models.ForeignKey(Task)
+  author = models.ForeignKey(User,verbose_name=_("Author"))
+  task = models.ForeignKey(Task,verbose_name=_("Task"))
   class Meta:
     verbose_name = _("Report")
     verbose_name_plural = _("Reports")
@@ -97,7 +97,7 @@ class Report(Object):
     pass

 class Category(models.Model):
-  title = models.CharField(max_length=64)
+  title = models.CharField(max_length=64,verbose_name=_("Name"))
   description = models.TextField(_("Description"))
   def __unicode__(self):
     return self.title
@@ -109,9 +109,9 @@ class Category(models.Model):
     pass

 class Document(Object):
-  category = models.ForeignKey(Category)
-  project = models.ForeignKey(Project)
-  author = models.ForeignKey(User)
+  category = models.ForeignKey(Category,verbose_name=_("Category"))
+  project = models.ForeignKey(Project,verbose_name=_("Project"))
+  author = models.ForeignKey(User,verbose_name=_("Author"))
   class Meta:
     verbose_name = _("Document")
     verbose_name_plural = _("Documents")
@@ -124,8 +124,8 @@ class Comment(models.Model):
   created = models.DateTimeField()
   object_id = models.IntegerField()
   object_type = models.CharField(max_length=10)
-  title = models.CharField(max_length=64,null=True)
-  text = models.TextField()
+  title = models.CharField(max_length=64,null=True,verbose_name=_("Title"))
+  text = models.TextField(_("Text"))
   class Admin:
     pass
   def __unicode__(self):
@@ -136,8 +136,8 @@ class Comment(models.Model):
     ordering = ("created",)

 class PrivateMsg(Object):
-  author = models.ForeignKey(User,related_name='sended_messages')
-  reciever = models.ForeignKey(User,related_name='recieved_messages')
+  author = models.ForeignKey(User,related_name='sended_messages',verbose_name=_("Author"))
+  reciever = models.ForeignKey(User,related_name='recieved_messages',verbose_name=_("To"))
   def __unicode__(self):
     return self.name + " from " + self.author.username
   class Meta:
diff --git a/mgmt/project_views.py b/mgmt/project_views.py
index 029109f..d416236 100644
--- a/mgmt/project_views.py
+++ b/mgmt/project_views.py
@@ -1,6 +1,7 @@
 from django.conf import settings
+from django.core.urlresolvers import reverse
 from decorators import check_auth,login_required,render_to
-from utils import get_comments,get_bugs
+from utils import get_comments,get_bugs,post_comment
 from models import *
 from rights import can
 from forms import CommentForm
@@ -8,23 +9,17 @@ from forms import CommentForm
 @check_auth(Project,'view')
 @render_to('project.html')
 def one_project(request,project):
-  if request.method=='POST':
-    title = request.POST['title']
-    text  = request.POST['text']
-    if not title:
-      title = text[:20]+'...'
-    c = Comment(created=datetime.now(),
-        author = request.user,
-        object_id = project.id,
-        object_type = 'Project',
-        title = title,
-        text = text)
-    c.save()
-  curr,pages,comments = get_comments(request,project.id,'Project')
   if can(request.user,'comment'):
     form = CommentForm()
   else:
     form = None
+
+  if request.method=='POST':
+    valid,form = post_comment(request,'Project',project.id, reverse('mgmt.views.one_project',args=(project.id,)))
+    if valid:     # Then `form' is HttpResponseRedirect
+      return form
+
+  curr,pages,comments = get_comments(request,project.id,'Project')
   for comment in comments:
     comment.can_delete = can(request.user,'delete',comment)
   return {'project': project,
diff --git a/mgmt/requests_views.py b/mgmt/requests_views.py
index afbd844..b34cb0e 100644
--- a/mgmt/requests_views.py
+++ b/mgmt/requests_views.py
@@ -1,7 +1,7 @@
 from django.http import HttpResponseForbidden,HttpResponseRedirect
 from django.core.urlresolvers import reverse
 from decorators import check_auth,login_required,render_to
-from utils import get_comments
+from utils import get_comments,post_comment
 from models import *
 from rights import can
 from forms import RequestForm,RequestStateForm,CommentForm
@@ -61,35 +61,28 @@ def edit_request(request,rq):
 @render_to('request.html')
 def one_request(request,rid):
   rq = Request.objects.get(pk=rid)
+
+  if can(request.user,'comment'):
+    form = CommentForm()
+  else:
+    form = None
+
   if request.method=='POST':
-    if request.POST['action']=='change_state':
-      new_state = request.POST['state']
-      rq.status = new_state
-      rq.save()
-    else:
-      title = request.POST['title']
-      text  = request.POST['text']
-      if not title:
-        title = text[:20]+'...'
-      c = Comment(created=datetime.now(),
-          author = request.user,
-          object_id = rid,
-          object_type = 'Request',
-          title = title,
-          text = text)
-      c.save()
-  can_change_state = can(request.user,'change_state',rq)
-  if can_change_state:
+    valid,form = post_comment(request,'Request',rid, reverse('mgmt.views.one_request',args=(rid,)))
+    if valid:        # Then `form' is HttpResponseRedirect
+      return form
+
+  if can(request.user,'change_state',rq):
     state_form = RequestStateForm({'state': rq.status})
   else:
     state_form = None
+
   can_edit = can(request.user,'edit',rq)
   tasks = rq.task_set.all()
   page,pages,comments = get_comments(request,rid,'Request')
-  if can(request.user,'comment'):
-    form = CommentForm()
-  else:
-    form = None
+  for c in comments:
+    c.can_delete = can(request.user,'delete',c)
+
   return {'request': rq,
        'tasks': tasks,
        'can_edit': can_edit,
diff --git a/mgmt/utils.py b/mgmt/utils.py
index 59023d6..7002a2b 100644
--- a/mgmt/utils.py
+++ b/mgmt/utils.py
@@ -1,3 +1,4 @@
+from django.http import HttpResponseRedirect
 from django.template import RequestContext
 from django.template.loader import get_template
 from django.http import HttpResponse
@@ -6,6 +7,7 @@ from django.conf import settings

 from context import *
 from models import *
+from forms import CommentForm

 #############
 # Utilites
@@ -22,6 +24,8 @@ def render_rss(template,dict,request):
   return HttpResponse(t.render(c),mimetype='application/xml')

 def get_comments(request,id,type):
+  """Return a list of comments on one page (specified in the request), for given object."""
+
   all = Comment.objects.filter(object_id=id, object_type=type)
   pg = Paginator(all,settings.COMMENTS_PER_PAGE)
   page_num = int(request.GET.get('page',1))
@@ -32,6 +36,8 @@ def get_comments(request,id,type):
   return page_num,range, page.object_list

 def get_bugs(request,pid=None):
+  """Return a list of bugs on one page (specified in the request), for given project."""
+
   if pid:
     all = Bug.objects.filter(project__pk=pid)
   else:
@@ -45,6 +51,8 @@ def get_bugs(request,pid=None):
   return page_num,range, page.object_list

 def get_comment_url(comment):
+  """Return URL for given Comment object."""
+
   type = comment.object_type
   id = comment.object_id
   if type=='Project':
@@ -55,3 +63,23 @@ def get_comment_url(comment):
     return "/docs/%d/#comment-%s" % (id,comment.id)
   if type=='Request':
     return "/requests/%d/#comment-%s" % (id,comment.id)
+
+def post_comment(request,type,id,redirect_to):
+  """Try post the comment, containing in request.POST,
+  for object with given `type' and `id'.
+  If success, return (True, HttpResponseRedirect(redirect_to)),
+  else return (False, form), where `form' is form with errors."""
+
+  form = CommentForm(request.POST)
+  if form.is_valid():
+    c = form.save(commit=False)
+    if 'title' not in form.cleaned_data or not form.cleaned_data['title']:
+      c.title = form.cleaned_data['text'][:20]+'...'
+    c.author = request.user
+    c.object_id = id
+    c.object_type = type
+    c.created = datetime.now()
+    c.save()
+    return True, HttpResponseRedirect(redirect_to)
+  else:
+    return False,form
ViewGit