[PATCH 6/9] py3: Fix Django models Python3 compatibility
Stephen Finucane
stephen.finucane at intel.com
Mon Nov 30 09:10:47 AEDT 2015
Per suggestions from the Django porting guide:
https://docs.djangoproject.com/en/1.8/topics/python3/
Signed-off-by: Stephen Finucane <stephen.finucane at intel.com>
---
patchwork/admin.py | 2 +-
patchwork/models.py | 74 ++++++++++++++++++++++++++++++++---------------------
2 files changed, 46 insertions(+), 30 deletions(-)
diff --git a/patchwork/admin.py b/patchwork/admin.py
index bada5a6..082885b 100644
--- a/patchwork/admin.py
+++ b/patchwork/admin.py
@@ -31,7 +31,7 @@ admin.site.register(Project, ProjectAdmin)
class PersonAdmin(admin.ModelAdmin):
- list_display = ('__unicode__', 'has_account')
+ list_display = ('__str__', 'has_account')
search_fields = ('name', 'email')
def has_account(self, person):
diff --git a/patchwork/models.py b/patchwork/models.py
index a2b9498..ecfd986 100644
--- a/patchwork/models.py
+++ b/patchwork/models.py
@@ -18,6 +18,8 @@
# along with Patchwork; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+from __future__ import absolute_import
+
from collections import Counter, OrderedDict
import datetime
import random
@@ -29,31 +31,37 @@ from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
from django.db import models
from django.db.models import Q
+from django.utils.encoding import python_2_unicode_compatible
from django.utils.functional import cached_property
+from django.utils import six
+from django.utils.six import add_metaclass
+from django.utils.six.moves import filter
from patchwork.parser import extract_tags, hash_patch
+ at python_2_unicode_compatible
class Person(models.Model):
email = models.CharField(max_length=255, unique=True)
name = models.CharField(max_length=255, null=True, blank=True)
user = models.ForeignKey(User, null=True, blank=True,
on_delete=models.SET_NULL)
- def __unicode__(self):
- if self.name:
- return u'%s <%s>' % (self.name, self.email)
- else:
- return self.email
-
def link_to_user(self, user):
self.name = user.profile.name()
self.user = user
+ def __str__(self):
+ if self.name:
+ return '%s <%s>' % (self.name, self.email)
+ else:
+ return self.email
+
class Meta:
verbose_name_plural = 'People'
+ at python_2_unicode_compatible
class Project(models.Model):
linkname = models.CharField(max_length=255, unique=True)
name = models.CharField(max_length=255, unique=True)
@@ -65,9 +73,6 @@ class Project(models.Model):
send_notifications = models.BooleanField(default=False)
use_tags = models.BooleanField(default=True)
- def __unicode__(self):
- return self.name
-
def is_editable(self, user):
if not user.is_authenticated():
return False
@@ -79,10 +84,14 @@ class Project(models.Model):
return []
return list(Tag.objects.all())
+ def __str__(self):
+ return self.name
+
class Meta:
ordering = ['linkname']
+ at python_2_unicode_compatible
class UserProfile(models.Model):
user = models.OneToOneField(User, unique=True, related_name='profile')
primary_project = models.ForeignKey(Project, null=True, blank=True)
@@ -98,8 +107,9 @@ class UserProfile(models.Model):
def name(self):
if self.user.first_name or self.user.last_name:
- names = filter(bool, [self.user.first_name, self.user.last_name])
- return u' '.join(names)
+ names = list(filter(
+ bool, [self.user.first_name, self.user.last_name]))
+ return ' '.join(names)
return self.user.username
def contributor_projects(self):
@@ -126,7 +136,7 @@ class UserProfile(models.Model):
action_required=True).values('pk').query)
return qs
- def __unicode__(self):
+ def __str__(self):
return self.name()
@@ -140,20 +150,21 @@ def _user_saved_callback(sender, created, instance, **kwargs):
models.signals.post_save.connect(_user_saved_callback, sender=User)
+ at python_2_unicode_compatible
class State(models.Model):
name = models.CharField(max_length=100)
ordering = models.IntegerField(unique=True)
action_required = models.BooleanField(default=True)
- def __unicode__(self):
+ def __str__(self):
return self.name
class Meta:
ordering = ['ordering']
+ at add_metaclass(models.SubfieldBase)
class HashField(models.CharField):
- __metaclass__ = models.SubfieldBase
def __init__(self, algorithm='sha1', *args, **kwargs):
self.algorithm = algorithm
@@ -161,13 +172,15 @@ class HashField(models.CharField):
import hashlib
def _construct(string=''):
+ if isinstance(string, six.text_type):
+ string = string.encode('utf-8')
return hashlib.new(self.algorithm, string)
self.construct = _construct
self.n_bytes = len(hashlib.new(self.algorithm).hexdigest())
except ImportError:
modules = {'sha1': 'sha', 'md5': 'md5'}
- if algorithm not in modules.keys():
+ if algorithm not in modules:
raise NameError("Unknown algorithm '%s'" % algorithm)
self.construct = __import__(modules[algorithm]).new
@@ -181,6 +194,7 @@ class HashField(models.CharField):
return 'char(%d)' % self.n_bytes
+ at python_2_unicode_compatible
class Tag(models.Model):
name = models.CharField(max_length=20)
pattern = models.CharField(
@@ -191,13 +205,13 @@ class Tag(models.Model):
max_length=2, unique=True, help_text='Short (one-or-two letter)'
' abbreviation for the tag, used in table column headers')
- def __unicode__(self):
- return self.name
-
@property
def attr_name(self):
return 'tag_%d_count' % self.id
+ def __str__(self):
+ return self.name
+
class Meta:
ordering = ['abbrev']
@@ -249,6 +263,7 @@ class PatchManager(models.Manager):
return self.get_queryset().with_tag_counts(project)
+ at python_2_unicode_compatible
class Patch(models.Model):
project = models.ForeignKey(Project)
msgid = models.CharField(max_length=255)
@@ -267,9 +282,6 @@ class Patch(models.Model):
objects = PatchManager()
- def __unicode__(self):
- return self.name
-
def commit_message(self):
"""Retrieve the commit message."""
return Comment.objects.filter(patch=self, msgid=self.msgid)
@@ -379,7 +391,7 @@ class Patch(models.Model):
unique[ctx] = check
- return unique.values()
+ return list(unique.values())
@property
def check_count(self):
@@ -403,6 +415,9 @@ class Patch(models.Model):
def get_absolute_url(self):
return ('patchwork.views.patch.patch', (), {'patch_id': self.id})
+ def __str__(self):
+ return self.name
+
class Meta:
verbose_name_plural = 'Patches'
ordering = ['date']
@@ -469,9 +484,6 @@ class Bundle(models.Model):
order=max_order + 1)
bp.save()
- class Meta:
- unique_together = [('owner', 'name')]
-
def public_url(self):
if not self.public:
return None
@@ -490,6 +502,9 @@ class Bundle(models.Model):
'bundlename': self.name,
})
+ class Meta:
+ unique_together = [('owner', 'name')]
+
class BundlePatch(models.Model):
patch = models.ForeignKey(Patch)
@@ -542,7 +557,7 @@ class Check(models.Model):
self.id, self.context, self.get_state_display())
def __unicode__(self):
- return ('%s (%s)' % (self.context, self.get_state_display()))
+ return '%s (%s)' % (self.context, self.get_state_display())
class EmailConfirmation(models.Model):
@@ -573,17 +588,18 @@ class EmailConfirmation(models.Model):
super(EmailConfirmation, self).save()
+ at python_2_unicode_compatible
class EmailOptout(models.Model):
email = models.CharField(max_length=200, primary_key=True)
- def __unicode__(self):
- return self.email
-
@classmethod
def is_optout(cls, email):
email = email.lower().strip()
return cls.objects.filter(email=email).count() > 0
+ def __str__(self):
+ return self.email
+
class PatchChangeNotification(models.Model):
patch = models.OneToOneField(Patch, primary_key=True)
--
2.0.0
More information about the Patchwork
mailing list