[Patchew-devel] [PATCH] models: use JSONField and JSONCharField

Paolo Bonzini posted 1 patch 6 years, 2 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/patchew-ci tags/patchew/20180426083340.9816-1-pbonzini@redhat.com
api/migrations/0026_auto_20180426_0829.py | 31 +++++++++++++++++++++++
api/models.py                             | 29 ++++++++-------------
api/rest.py                               |  5 ++--
requirements.txt                          |  1 +
4 files changed, 44 insertions(+), 22 deletions(-)
create mode 100644 api/migrations/0026_auto_20180426_0829.py
[Patchew-devel] [PATCH] models: use JSONField and JSONCharField
Posted by Paolo Bonzini 6 years, 2 months ago
Doing the JSON<->char conversion in the Field simplifies the model.
And because the accessor now returns a Python object rather than a
strict, it becomes possible to use a Serializer for sender and recipient
instead of a SerializerMethodFields.  This is important because
(as Shubham reminded me...) SerializerMethodField is read-only.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 api/migrations/0026_auto_20180426_0829.py | 31 +++++++++++++++++++++++
 api/models.py                             | 29 ++++++++-------------
 api/rest.py                               |  5 ++--
 requirements.txt                          |  1 +
 4 files changed, 44 insertions(+), 22 deletions(-)
 create mode 100644 api/migrations/0026_auto_20180426_0829.py

diff --git a/api/migrations/0026_auto_20180426_0829.py b/api/migrations/0026_auto_20180426_0829.py
new file mode 100644
index 0000000..acd5a63
--- /dev/null
+++ b/api/migrations/0026_auto_20180426_0829.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.12 on 2018-04-26 08:29
+from __future__ import unicode_literals
+
+from django.db import migrations
+import jsonfield.fields
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('api', '0025_populate_project_maintainers'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='message',
+            name='prefixes',
+            field=jsonfield.fields.JSONField(blank=True),
+        ),
+        migrations.AlterField(
+            model_name='message',
+            name='recipients',
+            field=jsonfield.fields.JSONField(),
+        ),
+        migrations.AlterField(
+            model_name='message',
+            name='sender',
+            field=jsonfield.fields.JSONCharField(db_index=True, max_length=4096),
+        ),
+    ]
diff --git a/api/models.py b/api/models.py
index 501070c..95fd6dd 100644
--- a/api/models.py
+++ b/api/models.py
@@ -21,6 +21,7 @@ from django.conf import settings
 from django.db import models
 from django.contrib.auth.models import User
 from django.urls import reverse
+import jsonfield
 from mbox import MboxMessage
 from event import emit_event, declare_event
 import lzma
@@ -262,9 +263,9 @@ class MessageManager(models.Manager):
                           subject=m.get_subject(),
                           stripped_subject=m.get_subject(strip_tags=True),
                           version=m.get_version(),
-                          sender=json.dumps(m.get_from()),
-                          recipients=json.dumps(m.get_to() + m.get_cc()),
-                          prefixes=json.dumps(m.get_prefixes()),
+                          sender=m.get_from(),
+                          recipients=m.get_to() + m.get_cc(),
+                          prefixes=m.get_prefixes(),
                           is_series_head=m.is_series_head(),
                           is_patch=m.is_patch(),
                           patch_num=m.get_num()[0])
@@ -303,10 +304,9 @@ class Message(models.Model):
     subject = HeaderFieldModel()
     stripped_subject = HeaderFieldModel(db_index=True)
     version = models.PositiveSmallIntegerField(default=0)
-    sender = HeaderFieldModel(db_index=True)
-    recipients = models.TextField()
-    # JSON encoded list
-    prefixes = models.TextField(blank=True)
+    sender = jsonfield.JSONCharField(max_length=4096, db_index=True)
+    recipients = jsonfield.JSONField()
+    prefixes = jsonfield.JSONField(blank=True)
     is_series_head = models.BooleanField()
     is_complete = models.BooleanField(default=False)
     is_patch = models.BooleanField()
@@ -333,13 +333,10 @@ class Message(models.Model):
         self._mbox_obj = MboxMessage(self.mbox)
         return self.mbox
 
-    def get_prefixes(self):
-        return json.loads(self.prefixes)
-
     def get_num(self):
         assert self.is_patch or self.is_series_head
         cur, total = 1, 1
-        for tag in self.get_prefixes():
+        for tag in self.prefixes:
             if '/' in tag:
                 n, m = tag.split('/')
                 try:
@@ -451,17 +448,11 @@ class Message(models.Model):
         emit_event("SetProperty", obj=self, name=prop, value=value,
                    old_value=old_val)
 
-    def get_sender(self):
-        return json.loads(self.sender)
-
-    def get_recipients(self):
-        return json.loads(self.recipients)
-
     def get_sender_addr(self):
-        return self.get_sender()[1]
+        return self.sender[1]
 
     def get_sender_name(self):
-        return self.get_sender()[0]
+        return self.sender[0]
 
     def _get_age(self, date):
         def _seconds_to_human(sec):
diff --git a/api/rest.py b/api/rest.py
index 381b569..e3aca3f 100644
--- a/api/rest.py
+++ b/api/rest.py
@@ -136,11 +136,10 @@ class BaseMessageSerializer(serializers.ModelSerializer):
         return d
 
     def get_recipients(self, obj):
-        return [self.format_name_addr(*x) for x in obj.get_recipients()]
+        return [self.format_name_addr(*x) for x in obj.recipients]
 
     def get_sender(self, obj):
-        name, addr = obj.get_sender()
-        return self.format_name_addr(*obj.get_sender())
+        return self.format_name_addr(*obj.sender)
 
 # a message_id is *not* unique, so we can only list
 class BaseMessageViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
diff --git a/requirements.txt b/requirements.txt
index 252f226..ac668e5 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,5 +4,6 @@ Markdown>=2.6.6
 django-debug-toolbar==1.8
 gunicorn>=19
 djangorestframework>=3.0.0
+jsonfield >= 2.0.2, <3.0
 drf-nested-routers
 coreapi-cli
\ No newline at end of file
-- 
2.17.0

_______________________________________________
Patchew-devel mailing list
Patchew-devel@redhat.com
https://www.redhat.com/mailman/listinfo/patchew-devel
Re: [Patchew-devel] [PATCH] models: use JSONField and JSONCharField
Posted by Fam Zheng 6 years, 2 months ago
On Thu, 04/26 10:33, Paolo Bonzini wrote:
> Doing the JSON<->char conversion in the Field simplifies the model.
> And because the accessor now returns a Python object rather than a
> strict, it becomes possible to use a Serializer for sender and recipient

"a string"?

> instead of a SerializerMethodFields.  This is important because
> (as Shubham reminded me...) SerializerMethodField is read-only.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  api/migrations/0026_auto_20180426_0829.py | 31 +++++++++++++++++++++++
>  api/models.py                             | 29 ++++++++-------------
>  api/rest.py                               |  5 ++--
>  requirements.txt                          |  1 +
>  4 files changed, 44 insertions(+), 22 deletions(-)
>  create mode 100644 api/migrations/0026_auto_20180426_0829.py
> 
> diff --git a/api/migrations/0026_auto_20180426_0829.py b/api/migrations/0026_auto_20180426_0829.py
> new file mode 100644
> index 0000000..acd5a63
> --- /dev/null
> +++ b/api/migrations/0026_auto_20180426_0829.py
> @@ -0,0 +1,31 @@
> +# -*- coding: utf-8 -*-
> +# Generated by Django 1.11.12 on 2018-04-26 08:29
> +from __future__ import unicode_literals
> +
> +from django.db import migrations
> +import jsonfield.fields
> +
> +
> +class Migration(migrations.Migration):
> +
> +    dependencies = [
> +        ('api', '0025_populate_project_maintainers'),
> +    ]
> +
> +    operations = [
> +        migrations.AlterField(
> +            model_name='message',
> +            name='prefixes',
> +            field=jsonfield.fields.JSONField(blank=True),
> +        ),
> +        migrations.AlterField(
> +            model_name='message',
> +            name='recipients',
> +            field=jsonfield.fields.JSONField(),
> +        ),
> +        migrations.AlterField(
> +            model_name='message',
> +            name='sender',
> +            field=jsonfield.fields.JSONCharField(db_index=True, max_length=4096),
> +        ),
> +    ]
> diff --git a/api/models.py b/api/models.py
> index 501070c..95fd6dd 100644
> --- a/api/models.py
> +++ b/api/models.py
> @@ -21,6 +21,7 @@ from django.conf import settings
>  from django.db import models
>  from django.contrib.auth.models import User
>  from django.urls import reverse
> +import jsonfield
>  from mbox import MboxMessage
>  from event import emit_event, declare_event
>  import lzma
> @@ -262,9 +263,9 @@ class MessageManager(models.Manager):
>                            subject=m.get_subject(),
>                            stripped_subject=m.get_subject(strip_tags=True),
>                            version=m.get_version(),
> -                          sender=json.dumps(m.get_from()),
> -                          recipients=json.dumps(m.get_to() + m.get_cc()),
> -                          prefixes=json.dumps(m.get_prefixes()),
> +                          sender=m.get_from(),
> +                          recipients=m.get_to() + m.get_cc(),
> +                          prefixes=m.get_prefixes(),
>                            is_series_head=m.is_series_head(),
>                            is_patch=m.is_patch(),
>                            patch_num=m.get_num()[0])
> @@ -303,10 +304,9 @@ class Message(models.Model):
>      subject = HeaderFieldModel()
>      stripped_subject = HeaderFieldModel(db_index=True)
>      version = models.PositiveSmallIntegerField(default=0)
> -    sender = HeaderFieldModel(db_index=True)
> -    recipients = models.TextField()
> -    # JSON encoded list
> -    prefixes = models.TextField(blank=True)
> +    sender = jsonfield.JSONCharField(max_length=4096, db_index=True)
> +    recipients = jsonfield.JSONField()
> +    prefixes = jsonfield.JSONField(blank=True)
>      is_series_head = models.BooleanField()
>      is_complete = models.BooleanField(default=False)
>      is_patch = models.BooleanField()
> @@ -333,13 +333,10 @@ class Message(models.Model):
>          self._mbox_obj = MboxMessage(self.mbox)
>          return self.mbox
>  
> -    def get_prefixes(self):
> -        return json.loads(self.prefixes)
> -
>      def get_num(self):
>          assert self.is_patch or self.is_series_head
>          cur, total = 1, 1
> -        for tag in self.get_prefixes():
> +        for tag in self.prefixes:
>              if '/' in tag:
>                  n, m = tag.split('/')
>                  try:
> @@ -451,17 +448,11 @@ class Message(models.Model):
>          emit_event("SetProperty", obj=self, name=prop, value=value,
>                     old_value=old_val)
>  
> -    def get_sender(self):
> -        return json.loads(self.sender)
> -
> -    def get_recipients(self):
> -        return json.loads(self.recipients)
> -
>      def get_sender_addr(self):
> -        return self.get_sender()[1]
> +        return self.sender[1]
>  
>      def get_sender_name(self):
> -        return self.get_sender()[0]
> +        return self.sender[0]
>  
>      def _get_age(self, date):
>          def _seconds_to_human(sec):
> diff --git a/api/rest.py b/api/rest.py
> index 381b569..e3aca3f 100644
> --- a/api/rest.py
> +++ b/api/rest.py
> @@ -136,11 +136,10 @@ class BaseMessageSerializer(serializers.ModelSerializer):
>          return d
>  
>      def get_recipients(self, obj):
> -        return [self.format_name_addr(*x) for x in obj.get_recipients()]
> +        return [self.format_name_addr(*x) for x in obj.recipients]
>  
>      def get_sender(self, obj):
> -        name, addr = obj.get_sender()
> -        return self.format_name_addr(*obj.get_sender())
> +        return self.format_name_addr(*obj.sender)
>  
>  # a message_id is *not* unique, so we can only list
>  class BaseMessageViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
> diff --git a/requirements.txt b/requirements.txt
> index 252f226..ac668e5 100644
> --- a/requirements.txt
> +++ b/requirements.txt
> @@ -4,5 +4,6 @@ Markdown>=2.6.6
>  django-debug-toolbar==1.8
>  gunicorn>=19
>  djangorestframework>=3.0.0
> +jsonfield >= 2.0.2, <3.0
>  drf-nested-routers
>  coreapi-cli
> \ No newline at end of file
> -- 
> 2.17.0
> 
> _______________________________________________
> Patchew-devel mailing list
> Patchew-devel@redhat.com
> https://www.redhat.com/mailman/listinfo/patchew-devel

_______________________________________________
Patchew-devel mailing list
Patchew-devel@redhat.com
https://www.redhat.com/mailman/listinfo/patchew-devel
Re: [Patchew-devel] [PATCH] models: use JSONField and JSONCharField
Posted by Paolo Bonzini 6 years, 2 months ago
On 27/04/2018 08:00, Fam Zheng wrote:
> On Thu, 04/26 10:33, Paolo Bonzini wrote:
>> Doing the JSON<->char conversion in the Field simplifies the model.
>> And because the accessor now returns a Python object rather than a
>> strict, it becomes possible to use a Serializer for sender and recipient
> 
> "a string"?

Obviously. :)

Paolo

_______________________________________________
Patchew-devel mailing list
Patchew-devel@redhat.com
https://www.redhat.com/mailman/listinfo/patchew-devel