Hello community,

here is the log from the commit of package python-django-extensions for 
openSUSE:Factory checked in at 2019-10-30 14:48:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-extensions (Old)
 and      /work/SRC/openSUSE:Factory/.python-django-extensions.new.2990 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-django-extensions"

Wed Oct 30 14:48:55 2019 rev:4 rq:744146 version:2.2.5

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-django-extensions/python-django-extensions.changes
        2019-10-08 19:57:54.788200576 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-django-extensions.new.2990/python-django-extensions.changes
      2019-10-30 14:48:59.926257569 +0100
@@ -1,0 +2,7 @@
+Wed Oct 30 12:02:11 UTC 2019 - Tomáš Chvátal <tchva...@suse.com>
+
+- Update to 2.2.5:
+  * RandomCharField, Support unique_together
+  * export_emails, add settings for overriding queryset fields, order_by and 
the full_name function
+
+-------------------------------------------------------------------

Old:
----
  django-extensions-2.2.3.tar.gz

New:
----
  django-extensions-2.2.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-django-extensions.spec ++++++
--- /var/tmp/diff_new_pack.JcNE4J/_old  2019-10-30 14:49:00.634258321 +0100
+++ /var/tmp/diff_new_pack.JcNE4J/_new  2019-10-30 14:49:00.638258325 +0100
@@ -18,7 +18,7 @@
 
 %define skip_python2 1
 Name:           python-django-extensions
-Version:        2.2.3
+Version:        2.2.5
 Release:        0
 Summary:        Extensions for Django
 License:        BSD-3-Clause

++++++ django-extensions-2.2.3.tar.gz -> django-extensions-2.2.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-extensions-2.2.3/.travis.yml 
new/django-extensions-2.2.5/.travis.yml
--- old/django-extensions-2.2.3/.travis.yml     2019-10-02 22:08:52.000000000 
+0200
+++ new/django-extensions-2.2.5/.travis.yml     2019-10-20 17:41:01.000000000 
+0200
@@ -13,15 +13,15 @@
       env: TOXENV=py36-flake8
     - python: 3.7
       env: TOXENV=py37-flake8
-      dist: xenial
-      sudo: required
-    - python: 3.6
+    - python: 3.8
+      env: TOXENV=py38-flake8
+    - python: 3.7
       env: TOXENV=precommit
-    - python: 3.6
+    - python: 3.7
       env: TOXENV=safety
-    - python: 3.6
+    - python: 3.7
       env: TOXENV=mypy
-    - python: 3.6
+    - python: 3.7
       env: TOXENV=compile-catalog
     - python: 2.7
       env: TOXENV=py27-dj111
@@ -37,48 +37,56 @@
       env: TOXENV=py36-djmaster
     - python: 3.7
       env: TOXENV=py37-dj21
-      dist: xenial
-      sudo: required
     - python: 3.7
       env: TOXENV=py37-dj22
-      dist: xenial
-      sudo: required
+    - python: 3.8
+      env: TOXENV=py38-dj22
     - python: 3.7
       env: TOXENV=py37-dj30
-      dist: xenial
-      sudo: required
+    - python: 3.8
+      env: TOXENV=py38-dj30
     - python: 3.7
       env: TOXENV=py37-dj22-postgres
-      dist: xenial
-      sudo: required
+      services:
+        - postgresql
+    - python: 3.8
+      env: TOXENV=py38-dj22-postgres
       services:
         - postgresql
     - python: 3.7
       env: TOXENV=py37-dj30-postgres
-      dist: xenial
-      sudo: required
+      services:
+        - postgresql
+    - python: 3.8
+      env: TOXENV=py38-dj30-postgres
       services:
         - postgresql
     - python: 3.7
       env: TOXENV=py37-dj22-mysql
-      dist: xenial
-      sudo: required
+      services:
+        - mysql
+    - python: 3.8
+      env: TOXENV=py38-dj22-mysql
       services:
         - mysql
     - python: 3.7
       env: TOXENV=py37-dj30-mysql
-      dist: xenial
-      sudo: required
+      services:
+        - mysql
+    - python: 3.8
+      env: TOXENV=py38-dj30-mysql
       services:
         - mysql
     - python: 3.7
       env: TOXENV=py37-djmaster
-      dist: xenial
-      sudo: required
+    - python: 3.8
+      env: TOXENV=py38-djmaster
     - python: 3.7
       env: TOXENV=py37-djmaster-postgres
-      dist: xenial
-      sudo: required
+      services:
+        - postgresql
+    - python: 3.8
+      env: TOXENV=py38-djmaster-postgres
       services:
         - postgresql
     - python: pypy2.7-5.10.0
@@ -97,8 +105,12 @@
       env: TOXENV=py36-djmaster
     - python: 3.7
       env: TOXENV=py37-djmaster
+    - python: 3.8
+      env: TOXENV=py38-djmaster
     - python: 3.7
       env: TOXENV=py37-djmaster-postgres
+    - python: 3.8
+      env: TOXENV=py38-djmaster-postgres
     - python: pypy3.5-5.10.1
       env: TOXENV=pypy3-djmaster
     - python: pypy2.7-5.10.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-extensions-2.2.3/CHANGELOG.md 
new/django-extensions-2.2.5/CHANGELOG.md
--- old/django-extensions-2.2.3/CHANGELOG.md    2019-10-02 22:08:52.000000000 
+0200
+++ new/django-extensions-2.2.5/CHANGELOG.md    2019-10-20 17:41:01.000000000 
+0200
@@ -1,6 +1,22 @@
 Changelog
 =========
 
+2.2.5
+-----
+
+Changes:
+ - Improvement: travis, add Python 3.8
+ - Improvement: setup.py, update classifiers
+
+
+2.2.4
+-----
+
+Changes:
+ - Improvement: RandomCharField, Support unique_together
+ - Improvement: export_emails, add settings for overriding queryset fields, 
order_by and the full_name function
+
+
 2.2.3
 -----
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.3/django_extensions/__init__.py 
new/django-extensions-2.2.5/django_extensions/__init__.py
--- old/django-extensions-2.2.3/django_extensions/__init__.py   2019-10-02 
22:08:52.000000000 +0200
+++ new/django-extensions-2.2.5/django_extensions/__init__.py   2019-10-20 
17:41:01.000000000 +0200
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-VERSION = (2, 2, 3)
+VERSION = (2, 2, 5)
 
 
 def get_version(version):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.3/django_extensions/db/fields/__init__.py 
new/django-extensions-2.2.5/django_extensions/db/fields/__init__.py
--- old/django-extensions-2.2.3/django_extensions/db/fields/__init__.py 
2019-10-02 22:08:52.000000000 +0200
+++ new/django-extensions-2.2.5/django_extensions/db/fields/__init__.py 
2019-10-20 17:41:01.000000000 +0200
@@ -340,6 +340,12 @@
             yield ''.join(get_random_string(self.length, chars))
         raise RuntimeError('max random character attempts exceeded (%s)' % 
self.max_unique_query_attempts)
 
+    def in_unique_together(self, model_instance):
+        for params in model_instance._meta.unique_together:
+            if self.attname in params:
+                return True
+        return False
+
     def pre_save(self, model_instance, add):
         if not add and getattr(model_instance, self.attname) != '':
             return getattr(model_instance, self.attname)
@@ -360,7 +366,7 @@
             population += string.punctuation
 
         random_chars = self.random_char_generator(population)
-        if not self.unique:
+        if not self.unique and not self.in_unique_together(model_instance):
             new = six.next(random_chars)
             setattr(model_instance, self.attname, new)
             return new
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.3/django_extensions/management/commands/export_emails.py
 
new/django-extensions-2.2.5/django_extensions/management/commands/export_emails.py
--- 
old/django-extensions-2.2.3/django_extensions/management/commands/export_emails.py
  2019-10-02 22:08:52.000000000 +0200
+++ 
new/django-extensions-2.2.5/django_extensions/management/commands/export_emails.py
  2019-10-20 17:41:01.000000000 +0200
@@ -2,6 +2,7 @@
 from __future__ import unicode_literals, print_function
 import sys
 
+from django.conf import settings
 from django.contrib.auth import get_user_model
 from django.contrib.auth.models import Group
 from django.core.management.base import BaseCommand, CommandError
@@ -20,12 +21,24 @@
 ]
 
 
-def full_name(first_name, last_name, username, **extra):
+def full_name(**kwargs):
     """Return full name or username."""
+    first_name = kwargs.get('first_name')
+    last_name = kwargs.get('last_name')
+
     name = " ".join(n for n in [first_name, last_name] if n)
-    if not name:
+    if name:
+        return name
+
+    name = kwargs.get('name')
+    if name:
+        return name
+
+    username = kwargs.get('username')
+    if username:
         return username
-    return name
+
+    return ""
 
 
 class Command(BaseCommand):
@@ -51,6 +64,9 @@
             help="output format. May be one of %s." % ", ".join(FORMATS),
         )
 
+    def full_name(self, **kwargs):
+        return getattr(settings, 'EXPORT_EMAILS_FULL_NAME_FUNC', 
full_name)(**kwargs)
+
     @signalcommand
     def handle(self, *args, **options):
         if len(args) > 1:
@@ -63,10 +79,13 @@
             raise CommandError("Unknown group '" + group + "'. Valid group 
names are: " + names)
 
         UserModel = get_user_model()
-        qs = UserModel.objects.all().order_by('last_name', 'first_name', 
'username', 'email')
+        order_by = getattr(settings, 'EXPORT_EMAILS_ORDER_BY', ['last_name', 
'first_name', 'username', 'email'])
+        fields = getattr(settings, 'EXPORT_EMAILS_FIELDS', ['last_name', 
'first_name', 'username', 'email'])
+
+        qs = UserModel.objects.all().order_by(*order_by)
         if group:
             qs = qs.filter(groups__name=group).distinct()
-        qs = qs.values('last_name', 'first_name', 'username', 'email')
+        qs = qs.values(*fields)
         getattr(self, options['format'])(qs)
 
     def address(self, qs):
@@ -74,7 +93,7 @@
         Single entry per line in the format of:
             "full name" <m...@address.com>;
         """
-        self.stdout.write("\n".join('"%s" <%s>;' % (full_name(**ent), 
ent['email']) for ent in qs))
+        self.stdout.write("\n".join('"%s" <%s>;' % (self.full_name(**ent), 
ent.get('email', '')) for ent in qs))
         self.stdout.write("\n")
 
     def emails(self, qs):
@@ -82,7 +101,7 @@
         Single entry with email only in the format of:
             m...@address.com,
         """
-        self.stdout.write(",\n".join(ent['email'] for ent in qs))
+        self.stdout.write(",\n".join(ent['email'] for ent in qs if 
ent.get('email')))
         self.stdout.write("\n")
 
     def google(self, qs):
@@ -90,7 +109,7 @@
         csvf = writer(sys.stdout)
         csvf.writerow(['Name', 'Email'])
         for ent in qs:
-            csvf.writerow([full_name(**ent), ent['email']])
+            csvf.writerow([self.full_name(**ent), ent.get('email', '')])
 
     def linkedin(self, qs):
         """
@@ -100,7 +119,7 @@
         csvf = writer(sys.stdout)
         csvf.writerow(['First Name', 'Last Name', 'Email'])
         for ent in qs:
-            csvf.writerow([ent['first_name'], ent['last_name'], ent['email']])
+            csvf.writerow([ent.get('first_name', ''), ent.get('last_name', 
''), ent.get('email', '')])
 
     def outlook(self, qs):
         """CSV format suitable for importing into outlook"""
@@ -112,7 +131,7 @@
         csvf.writerow(columns)
         empty = [''] * (len(columns) - 2)
         for ent in qs:
-            csvf.writerow([full_name(**ent), ent['email']] + empty)
+            csvf.writerow([self.full_name(**ent), ent.get('email', '')] + 
empty)
 
     def vcard(self, qs):
         """VCARD format."""
@@ -125,14 +144,15 @@
         out = sys.stdout
         for ent in qs:
             card = vobject.vCard()
-            card.add('fn').value = full_name(**ent)
-            if not ent['last_name'] and not ent['first_name']:
-                # fallback to fullname, if both first and lastname are not 
declared
-                card.add('n').value = vobject.vcard.Name(full_name(**ent))
-            else:
+            card.add('fn').value = self.full_name(**ent)
+            if ent.get('last_name') and ent.get('first_name'):
                 card.add('n').value = vobject.vcard.Name(ent['last_name'], 
ent['first_name'])
-            emailpart = card.add('email')
-            emailpart.value = ent['email']
-            emailpart.type_param = 'INTERNET'
+            else:
+                # fallback to fullname, if both first and lastname are not 
declared
+                card.add('n').value = vobject.vcard.Name(self.full_name(**ent))
+            if ent.get('email'):
+                emailpart = card.add('email')
+                emailpart.value = ent['email']
+                emailpart.type_param = 'INTERNET'
 
             out.write(card.serialize())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-extensions-2.2.3/docs/conf.py 
new/django-extensions-2.2.5/docs/conf.py
--- old/django-extensions-2.2.3/docs/conf.py    2019-10-02 22:08:52.000000000 
+0200
+++ new/django-extensions-2.2.5/docs/conf.py    2019-10-20 17:41:01.000000000 
+0200
@@ -47,7 +47,7 @@
 # The short X.Y version.
 version = '2.2'
 # The full version, including alpha/beta/rc tags.
-release = '2.2.3'
+release = '2.2.5'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-extensions-2.2.3/docs/export_emails.rst 
new/django-extensions-2.2.5/docs/export_emails.rst
--- old/django-extensions-2.2.3/docs/export_emails.rst  2019-10-02 
22:08:52.000000000 +0200
+++ new/django-extensions-2.2.5/docs/export_emails.rst  2019-10-20 
17:41:01.000000000 +0200
@@ -78,4 +78,40 @@
 
 A vCard format which Apple Address Book can parse and import.
 
+
+Settings
+--------
+
+There are a couple of settings keys which can be configured in `settings.py`.
+Below the default values are shown:
+
+```
+EXPORT_EMAILS_ORDER_BY = ['last_name', 'first_name', 'username', 'email']
+EXPORT_EMAILS_FIELDS = ['last_name', 'first_name', 'username', 'email']
+EXPORT_EMAILS_FULL_NAME_FUNC = None
+```
+
+EXPORT_EMAILS_ORDER_BY
+~~~~~~~~~~~~~~~~~~~~~~
+
+Specifies the `order_by(...)` clause on the query being done into the databse 
to
+retreive the users. This determines the order of the output.
+
+
+EXPORT_EMAILS_FIELDS
+~~~~~~~~~~~~~~~~~~~~
+
+Specifies which fields will be selected from the database. This is most useful 
in
+combination with `EXPORT_EMAILS_FULL_NAME_FUNC` to select other fields you 
might
+want to use inside the custom function or when using a custom User model which
+does not have fields like 'first_name' and 'last_name'.
+
+EXPORT_EMAILS_FULL_NAME_FUNC
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A function to use to create a full name based on the database fields selected 
by
+`EXPORT_EMAILS_FULL_NAME_FUNC`. The default implementation can be looked up in
+https://github.com/django-extensions/django-extensions/blob/master/django_extensions/management/commands/export_emails.py#L23
+
+
 .. _`LinkedIn Groups`: http://www.linkedin.com/static?key=groups_info
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-extensions-2.2.3/docs/index.rst 
new/django-extensions-2.2.5/docs/index.rst
--- old/django-extensions-2.2.3/docs/index.rst  2019-10-02 22:08:52.000000000 
+0200
+++ new/django-extensions-2.2.5/docs/index.rst  2019-10-20 17:41:01.000000000 
+0200
@@ -77,6 +77,7 @@
    sqldsn
    validate_templates
    validators
+   admin_generator
 
 
 Indices and tables
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-extensions-2.2.3/setup.py 
new/django-extensions-2.2.5/setup.py
--- old/django-extensions-2.2.3/setup.py        2019-10-02 22:08:52.000000000 
+0200
+++ new/django-extensions-2.2.5/setup.py        2019-10-20 17:41:01.000000000 
+0200
@@ -171,8 +171,8 @@
         'Environment :: Web Environment',
         'Framework :: Django',
         'Framework :: Django :: 1.11',
-        'Framework :: Django :: 2.0',
         'Framework :: Django :: 2.1',
+        'Framework :: Django :: 2.2',
         'Intended Audience :: Developers',
         'License :: OSI Approved :: MIT License',
         'Operating System :: OS Independent',
@@ -180,10 +180,10 @@
         'Programming Language :: Python :: 2',
         'Programming Language :: Python :: 2.7',
         'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.4',
         'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: 3.7',
+        'Programming Language :: Python :: 3.8',
         'Programming Language :: Python :: Implementation :: CPython',
         'Programming Language :: Python :: Implementation :: PyPy',
         'Topic :: Utilities',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.3/tests/test_randomchar_field.py 
new/django-extensions-2.2.5/tests/test_randomchar_field.py
--- old/django-extensions-2.2.3/tests/test_randomchar_field.py  2019-10-02 
22:08:52.000000000 +0200
+++ new/django-extensions-2.2.5/tests/test_randomchar_field.py  2019-10-20 
17:41:01.000000000 +0200
@@ -7,6 +7,7 @@
 from .testapp.models import RandomCharTestModel, RandomCharTestModelUnique, 
RandomCharTestModelLowercase
 from .testapp.models import RandomCharTestModelUppercase, 
RandomCharTestModelAlpha, RandomCharTestModelDigits
 from .testapp.models import RandomCharTestModelPunctuation, 
RandomCharTestModelLowercaseAlphaDigits, RandomCharTestModelUppercaseAlphaDigits
+from .testapp.models import RandomCharTestModelUniqueTogether
 
 try:
     from unittest import mock
@@ -86,3 +87,15 @@
             m = RandomCharTestModelUnique()
             with pytest.raises(RuntimeError):
                 m.save()
+
+    def testRandomCharTestModelUniqueTogether(self):
+        with mock.patch('django_extensions.db.fields.get_random_string') as 
mock_sample:
+            mock_sample.return_value = 'aaa'
+            m = RandomCharTestModelUniqueTogether()
+            m.common_field = 'bbb'
+            m.save()
+
+            m = RandomCharTestModelUniqueTogether()
+            m.common_field = 'bbb'
+            with pytest.raises(RuntimeError):
+                m.save()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-extensions-2.2.3/tests/testapp/models.py 
new/django-extensions-2.2.5/tests/testapp/models.py
--- old/django-extensions-2.2.3/tests/testapp/models.py 2019-10-02 
22:08:52.000000000 +0200
+++ new/django-extensions-2.2.5/tests/testapp/models.py 2019-10-20 
17:41:01.000000000 +0200
@@ -351,6 +351,15 @@
         app_label = 'django_extensions'
 
 
+class RandomCharTestModelUniqueTogether(models.Model):
+    random_char_field = RandomCharField(length=8)
+    common_field = models.CharField(max_length=10)
+
+    class Meta:
+        app_label = 'django_extensions'
+        unique_together = ('random_char_field', 'common_field')
+
+
 class TimestampedTestModel(TimeStampedModel):
     class Meta:
         app_label = 'django_extensions'


Reply via email to