Review Board

beta

Migrate to newforms-admin and django.forms

Updated 5 months, 2 weeks ago

Christian Hammond Reviewers
trunk reviewboard
None Review Board SVN
The Django newforms-admin and full newforms migrations happened in trunk recently, so we needed to update accordingly.

This change strips out all the inner Admin classes from the models and moves to the new Admin classes in admin.py files. We auto-discover early on (making sure we only do it once so that we don't break unit tests -- will need to ask Django to fix this in the future). We also move to importing django.forms instead of django.newforms.
Ran all unit tests and made sure the admin site was working as expected.

Diff revision 1 (Latest)

  1. /trunk/reviewboard/manage.py: 2 changes [ 1 2 ]
  2. /trunk/reviewboard/urls.py: 2 changes [ 1 2 ]
  3. /trunk/reviewboard/accounts/admin.py: 1 change [ new content ]
  4. /trunk/reviewboard/accounts/forms.py: 2 changes [ 1 2 ]
  5. /trunk/reviewboard/accounts/models.py: 6 changes [ 1 2 3 4 5 6 ]
  6. /trunk/reviewboard/admin/urls.py: 2 changes [ 1 2 ]
  7. /trunk/reviewboard/diffviewer/admin.py: 1 change [ new content ]
  8. /trunk/reviewboard/diffviewer/forms.py: 1 change [ 1 ]
  9. /trunk/reviewboard/diffviewer/models.py: 6 changes [ 1 2 3 4 5 6 ]
  10. /trunk/reviewboard/htdocs/media/admin/css/forms.css: 1 change [ 1 ]
  11. /trunk/reviewboard/htdocs/media/admin/js/urlify.js: 1 change [ 1 ]
  12. /trunk/reviewboard/htdocs/media/admin/js/admin/CollapsedFieldsets.js: 1 change [ 1 ]
  13. /trunk/reviewboard/htdocs/media/admin/js/admin/RelatedObjectLookups.js: 2 changes [ 1 2 ]
  14. /trunk/reviewboard/reviews/admin.py: 1 change [ new content ]
  15. /trunk/reviewboard/reviews/forms.py: 1 change [ 1 ]
  16. /trunk/reviewboard/reviews/models.py: 48 changes [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 ]
  17. /trunk/reviewboard/scmtools/admin.py: 1 change [ new content ]
  18. /trunk/reviewboard/scmtools/models.py: 3 changes [ 1 2 3 ]
  19. /trunk/reviewboard/templates/admin/base_site.html: 1 change [ 1 ]
  20. /trunk/reviewboard/templates/admin/dashboard.html: 1 change [ 1 ]
  21. /trunk/reviewboard/templates/admin/database.html: 2 changes [ 1 2 ]
  22. /trunk/reviewboard/templates/admin/index.html: 2 changes [ 1 2 ]
/trunk/reviewboard/manage.py
Revision 1401 New Change
25
    # Python 2.4
25
    # Python 2.4
26
    if sys.version_info[0] < 2 or \
26
    if sys.version_info[0] < 2 or \
27
       (sys.version_info[0] == 2 and sys.version_info[1] < 4):
27
       (sys.version_info[0] == 2 and sys.version_info[1] < 4):
28
        dependency_error('Python 2.4 or newer is required.')
28
        dependency_error('Python 2.4 or newer is required.')
29
29
30
    # Django 0.97
30
    # Django ~1.0 alpha
31
    try:
31
    try:
32
        import django
32
        import django
33
        if django.VERSION[0] == 0 and django.VERSION[1] < 97:
33
        if django.VERSION[0] == 0 and django.VERSION[1] < 97:
34
            raise ImportError
34
            raise ImportError
35
35
36
        # QuerySet refactor (r7477)
36
        # newforms-admin and newforms -> forms (r7971)
37
        from django.core.exceptions import FieldError
37
        import django.forms.widgets
38
    except ImportError:
38
    except ImportError:
39
        dependency_error("Django > 0.97 (or SVN >= r7477) is required.")
39
        dependency_error("Django > 0.97 (or SVN >= r7477) is required.")
40
40
41
    # django-evolution
41
    # django-evolution
42
    try:
42
    try:
/trunk/reviewboard/urls.py
Revision 1401 New Change
1
import os.path
1
import os.path
2
2
3
from django.conf import settings
3
from django.conf import settings
4
from django.conf.urls.defaults import patterns, include, url
4
from django.conf.urls.defaults import patterns, include, url
5
from django.contrib import admin
5
6
6
from reviewboard.admin.checks import check_updates_required
7
from reviewboard.admin.checks import check_updates_required
7
from reviewboard.reviews.feeds import RssReviewsFeed, AtomReviewsFeed, \
8
from reviewboard.reviews.feeds import RssReviewsFeed, AtomReviewsFeed, \
8
                                      RssSubmitterReviewsFeed, \
9
                                      RssSubmitterReviewsFeed, \
9
                                      AtomSubmitterReviewsFeed, \
10
                                      AtomSubmitterReviewsFeed, \
10
                                      RssGroupReviewsFeed, \
11
                                      RssGroupReviewsFeed, \
11
                                      AtomGroupReviewsFeed
12
                                      AtomGroupReviewsFeed
12
13
13
14
15
# Load in all the models for the admin UI.
16
if not admin.site._registry:
17
    admin.autodiscover()
18
19
14
# URLs global to all modes
20
# URLs global to all modes
15
urlpatterns = patterns('',
21
urlpatterns = patterns('',
16
    (r'^admin/', include('reviewboard.admin.urls')),
22
    (r'^admin/', include('reviewboard.admin.urls')),
17
)
23
)
18
24
/trunk/reviewboard/accounts/admin.py
New File
1
from django.contrib import admin
2
3
from reviewboard.accounts.models import ReviewRequestVisit, Profile
4
5
6
class ProfileAdmin(admin.ModelAdmin):
7
    list_display = ('__unicode__', 'first_time_setup_done')
8
    raw_id_fields = ('user', 'starred_review_requests', 'starred_groups')
9
10
11
print "Registering ReviewRequestVisit"
12
admin.site.register(ReviewRequestVisit)
13
admin.site.register(Profile, ProfileAdmin)
/trunk/reviewboard/accounts/forms.py
Revision 1401 New Change
1
from django import newforms as forms
1
from django import forms
2
from django.conf import settings
2
from django.conf import settings
3
from django.newforms import widgets
3
from django.forms import widgets
4
from django.utils.translation import ugettext as _
4
from django.utils.translation import ugettext as _
5
5
6
from reviewboard.reviews.models import Group
6
from reviewboard.reviews.models import Group
7
7
8
8
/trunk/reviewboard/accounts/models.py
Revision 1401 New Change
1
from datetime import datetime
1
from datetime import datetime
2
2
3
from django.contrib.auth.models import User
3
from django.contrib.auth.models import User
4
from django.db import models
4
from django.db import models
5
from django.utils.translation import ugettext_lazy as _
5
from django.utils.translation import ugettext_lazy as _
6
6
7
from djblets.util.db import ConcurrencyManager
7
from djblets.util.db import ConcurrencyManager
8
8
9
from reviewboard.reviews.models import Group, ReviewRequest
9
from reviewboard.reviews.models import Group, ReviewRequest
10
10
11
11
12
# Hack the admin display to include the is_active field
12
# Hack the admin display to include the is_active field
13
User._meta.admin.list_display += ('is_active',)
13
#User._meta.admin.list_display += ('is_active',)
14
User._meta.admin.list_filter += ('is_active',)
14
#User._meta.admin.list_filter += ('is_active',)
15
15
16
16
17
class ReviewRequestVisit(models.Model):
17
class ReviewRequestVisit(models.Model):
18
    """
18
    """
19
    A recording of the last time a review request was visited by a user.
19
    A recording of the last time a review request was visited by a user.
75
75
76
    # A list of starred review requests. This allows users to monitor a
76
    # A list of starred review requests. This allows users to monitor a
77
    # review request and receive e-mails on updates without actually being
77
    # review request and receive e-mails on updates without actually being
78
    # on the reviewer list or commenting on the review. This is similar to
78
    # on the reviewer list or commenting on the review. This is similar to
79
    # adding yourself to a CC list.
79
    # adding yourself to a CC list.
80
    starred_review_requests = models.ManyToManyField(
80
    starred_review_requests = models.ManyToManyField(ReviewRequest,
81
        ReviewRequest, core=False, blank=True,
81
                                                     core=False, blank=True,
82
        filter_interface=models.HORIZONTAL,
83
        related_name="starred_by")
82
                                                     related_name="starred_by")
84
83
85
    # A list of watched groups. This is so that users can monitor groups
84
    # A list of watched groups. This is so that users can monitor groups
86
    # without actually joining them, preventing e-mails being sent to the
85
    # without actually joining them, preventing e-mails being sent to the
87
    # user and review requests from entering the Incoming Reviews list.
86
    # user and review requests from entering the Incoming Reviews list.
88
    starred_groups = models.ManyToManyField(
87
    starred_groups = models.ManyToManyField(Group, core=False, blank=True,
89
        Group, core=False, blank=True, filter_interface=models.HORIZONTAL,
90
        related_name="starred_by")
88
                                            related_name="starred_by")
91
89
92
    def __unicode__(self):
90
    def __unicode__(self):
93
        return self.user.username
91
        return self.user.username
94
95
    class Admin:
96
        list_display = ('__unicode__', 'first_time_setup_done')
/trunk/reviewboard/admin/urls.py
Revision 1401 New Change
1
from django.conf.urls.defaults import *
1
from django.conf.urls.defaults import *
2
from django.contrib import admin
2
3
3
4
4
NEWS_FEED = "http://www.review-board.org/news/feed/"
5
NEWS_FEED = "http://www.review-board.org/news/feed/"
5
6
6
urlpatterns = patterns('reviewboard.admin.views',
7
urlpatterns = patterns('reviewboard.admin.views',
7
    ('^$', 'dashboard'),
8
    ('^$', 'dashboard'),
8
    ('^cache/$', 'cache_stats'),
9
    ('^cache/$', 'cache_stats'),
9
)
10
)
10
11
11
urlpatterns += patterns('',
12
urlpatterns += patterns('',
12
    ('^db/', include('django.contrib.admin.urls')),
13
    ('^db/(.*)', admin.site.root),
13
    ('^feed/news/$', 'djblets.feedview.views.view_feed',
14
    ('^feed/news/$', 'djblets.feedview.views.view_feed',
14
     {'template_name': 'admin/feed.html',
15
     {'template_name': 'admin/feed.html',
15
      'url': NEWS_FEED}),
16
      'url': NEWS_FEED}),
16
    ('^feed/news/rss/$', 'django.views.generic.simple.redirect_to',
17
    ('^feed/news/rss/$', 'django.views.generic.simple.redirect_to',
17
     {'url': NEWS_FEED}),
18
     {'url': NEWS_FEED}),
18
)
19
)
/trunk/reviewboard/diffviewer/admin.py
New File
1
from django.contrib import admin
2
3
from reviewboard.diffviewer.models import FileDiff, DiffSet, DiffSetHistory
4
5
6
class FileDiffAdmin(admin.ModelAdmin):
7
    fieldsets = (
8
        (None, {
9
            'fields': ('diffset', ('source_file', 'source_revision'),
10
                       ('dest_file', 'dest_detail'),
11
                       'binary', 'diff', 'parent_diff')
12
        }),
13
    )
14
    list_display = ('source_file', 'source_revision',
15
                    'dest_file', 'dest_detail')
16
    raw_id_fields = ('diffset',)
17
18
19
class DiffSetAdmin(admin.ModelAdmin):
20
    list_display = ('__unicode__', 'revision', 'timestamp')
21
    raw_id_fields = ('history',)
22
23
24
admin.site.register(FileDiff, FileDiffAdmin)
25
admin.site.register(DiffSet, DiffSetAdmin)
26
admin.site.register(DiffSetHistory)
/trunk/reviewboard/diffviewer/forms.py
Revision 1401 New Change
1
import os
1
import os
2
2
3
from django import newforms as forms
3
from django import forms
4
from django.utils.encoding import smart_unicode
4
from django.utils.encoding import smart_unicode
5
from django.utils.translation import ugettext as _
5
from django.utils.translation import ugettext as _
6
6
7
from reviewboard.diffviewer.diffutils import DEFAULT_DIFF_COMPAT_VERSION
7
from reviewboard.diffviewer.diffutils import DEFAULT_DIFF_COMPAT_VERSION
8
from reviewboard.diffviewer.models import DiffSet, FileDiff
8
from reviewboard.diffviewer.models import DiffSet, FileDiff
/trunk/reviewboard/diffviewer/models.py
Revision 1401 New Change
14
    This contains the patch and information needed to produce original and
14
    This contains the patch and information needed to produce original and
15
    patched versions of a single file in a repository.
15
    patched versions of a single file in a repository.
16
    """
16
    """
17
    diffset = models.ForeignKey('DiffSet', edit_inline=models.STACKED,
17
    diffset = models.ForeignKey('DiffSet', edit_inline=models.STACKED,
18
                                related_name='files',
18
                                related_name='files',
19
                                verbose_name=_("diff set"),
19
                                verbose_name=_("diff set"))
20
                                raw_id_admin=True)
21
20
22
    source_file = models.CharField(_("source file"), max_length=256, core=True)
21
    source_file = models.CharField(_("source file"), max_length=256, core=True)
23
    dest_file = models.CharField(_("destination file"), max_length=256,
22
    dest_file = models.CharField(_("destination file"), max_length=256,
24
                                 core=True)
23
                                 core=True)
25
    source_revision = models.CharField(_("source file revision"), max_length=512)
24
    source_revision = models.CharField(_("source file revision"), max_length=512)
31
30
32
    def __unicode__(self):
31
    def __unicode__(self):
33
        return u"%s (%s) -> %s (%s)" % (self.source_file, self.source_revision,
32
        return u"%s (%s) -> %s (%s)" % (self.source_file, self.source_revision,
34
                                        self.dest_file, self.dest_detail)
33
                                        self.dest_file, self.dest_detail)
35
34
36
    class Admin:
37
        list_display = ('source_file', 'source_revision',
38
                        'dest_file', 'dest_detail')
39
        fields = (
40
            (None, {
41
                'fields': ('diffset', ('source_file', 'source_revision'),
42
                           ('dest_file', 'dest_detail'),
43
                           'binary', 'diff', 'parent_diff')
44
            }),
45
        )
46
47
35
48
class DiffSet(models.Model):
36
class DiffSet(models.Model):
49
    """
37
    """
50
    A revisioned collection of FileDiffs.
38
    A revisioned collection of FileDiffs.
51
    """
39
    """
52
    name = models.CharField(_('name'), max_length=256, core=True)
40
    name = models.CharField(_('name'), max_length=256, core=True)
53
    revision = models.IntegerField(_("revision"), core=True)
41
    revision = models.IntegerField(_("revision"), core=True)
54
    timestamp = models.DateTimeField(_("timestamp"), default=datetime.now)
42
    timestamp = models.DateTimeField(_("timestamp"), default=datetime.now)
55
    history = models.ForeignKey('DiffSetHistory', null=True, core=True,
43
    history = models.ForeignKey('DiffSetHistory', null=True, core=True,
56
                                raw_id_admin=True,
57
                                related_name="diffsets",
44
                                related_name="diffsets",
58
                                verbose_name=_("diff set history"))
45
                                verbose_name=_("diff set history"))
59
    repository = models.ForeignKey(Repository, related_name="diffsets",
46
    repository = models.ForeignKey(Repository, related_name="diffsets",
60
                                   verbose_name=_("repository"))
47
                                   verbose_name=_("repository"))
61
    diffcompat = models.IntegerField(
48
    diffcompat = models.IntegerField(
82
        super(DiffSet, self).save()
69
        super(DiffSet, self).save()
83
70
84
    def __unicode__(self):
71
    def __unicode__(self):
85
        return u"[%s] %s r%s" % (self.id, self.name, self.revision)
72
        return u"[%s] %s r%s" % (self.id, self.name, self.revision)
86
73
87
    class Admin:
88
        list_display = ('__unicode__', 'revision', 'timestamp')
89
90
    class Meta:
74
    class Meta:
91
        get_latest_by = 'revision'
75
        get_latest_by = 'revision'
92
        ordering = ['revision', 'timestamp']
76
        ordering = ['revision', 'timestamp']
93
77
94
78
103
    timestamp = models.DateTimeField(_("timestamp"), default=datetime.now)
87
    timestamp = models.DateTimeField(_("timestamp"), default=datetime.now)
104
88
105
    def __unicode__(self):
89
    def __unicode__(self):
106
        return u'Diff Set History (%s revisions)' % self.diffsets.count()
90
        return u'Diff Set History (%s revisions)' % self.diffsets.count()
107
91
108
    class Admin:
92
    class Meta:
109
        pass
93
        verbose_name_plural = "Diff set histories"
/trunk/reviewboard/htdocs/media/admin/css/forms.css
Revision 1401 New Change
56
.vDateField, .vTimeField { margin-right:2px; }
56
.vDateField, .vTimeField { margin-right:2px; }
57
.vURLField { width:30em; }
57
.vURLField { width:30em; }
58
.vLargeTextField, .vXMLLargeTextField { width:48em; }
58
.vLargeTextField, .vXMLLargeTextField { width:48em; }
59
.flatpages-flatpage #id_content { height:40.2em; }
59
.flatpages-flatpage #id_content { height:40.2em; }
60
.module table .vPositiveSmallIntegerField { width:2.2em; }
60
.module table .vPositiveSmallIntegerField { width:2.2em; }
61
62
/* x unsorted */
63
.inline-group {padding:10px; padding-bottom:5px; background:#eee; margin:10px 0;}
64
.inline-group h3.header {margin:-5px -10px 5px -10px; background:#bbb; color:#fff; padding:2px 5px 3px 5px; font-size:11px}
65
.inline-related {margin-bottom:15px; position:relative;}
66
.last-related {margin-bottom:0px;}
67
.inline-related h2 { margin:0; padding:2px 5px 3px 5px; font-size:11px; text-align:left; font-weight:bold;  color:#888; }
68
.inline-related h2 b {font-weight:normal; color:#aaa;}
69
.inline-related h2 span.delete {padding-left:20px; position:absolute; top:0px; right:5px;}
70
.inline-related h2 span.delete label {margin-left:2px; padding-top:1px;}
71
.inline-related fieldset {background:#fbfbfb;}
72
.inline-related fieldset.module h2 { margin:0; padding:2px 5px 3px 5px; font-size:11px; text-align:left; font-weight:bold; background:#bcd; color:#fff; }
73
.inline-related.tabular fieldset.module table {width:100%;}
74
75
.inline-group .tabular tr.has_original td {padding-top:2em;}
76
.inline-group .tabular tr td.original { padding:2px 0 0 0; width:0; _position:relative; }
77
.inline-group .tabular th.original {width:0px; padding:0;}
78
.inline-group .tabular td.original p {position:absolute; left:0; height:1.1em; padding:2px 7px; overflow:hidden; font-size:9px; font-weight:bold; color:#666; _width:700px;     }
79
.inline-group ul.tools {padding:0; margin: 0; list-style:none;}
80
.inline-group ul.tools li {display:inline; padding:0 5px;}
81
.inline-group ul.tools a.add {background:url(../img/admin/icon_addlink.gif) 0 50% no-repeat; padding-left:14px;}
/trunk/reviewboard/htdocs/media/admin/js/urlify.js
Revision 1401 New Change
1
var LATIN_MAP = {
1
var LATIN_MAP = {
2
    'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç':
2
    'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç':
3
    'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I',
3
    'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I',
4
    'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö':
4
    'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö':
5
    'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ű': 'U',
5
    'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ű': 'U',
6
    'Ý': 'Y', 'Þ': 'TH', 'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã': 'a', 'ä':
6
    'Ý': 'Y', 'Þ': 'TH', 'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã': 'a', 'ä':
7
    'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e',
7
    'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e',
8
    'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'o', 'ñ': 'n'