Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-django-tastypie for
openSUSE:Factory checked in at 2022-02-26 17:02:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-tastypie (Old)
and /work/SRC/openSUSE:Factory/.python-django-tastypie.new.1958 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-django-tastypie"
Sat Feb 26 17:02:12 2022 rev:17 rq:957670 version:0.14.4
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-django-tastypie/python-django-tastypie.changes
2021-06-09 21:53:14.706575593 +0200
+++
/work/SRC/openSUSE:Factory/.python-django-tastypie.new.1958/python-django-tastypie.changes
2022-02-26 17:02:43.859542078 +0100
@@ -1,0 +2,8 @@
+Fri Feb 25 21:59:18 UTC 2022 - Matej Cepl <[email protected]>
+
+- Update to 0.14.4:
+ - Django 4.0 support
+- Fix testing of the package.
+- Remove upstreamed patch merged_pr_1624_chunk.patch
+
+-------------------------------------------------------------------
Old:
----
merged_pr_1624_chunk.patch
v0.14.3.tar.gz
New:
----
v0.14.4.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-django-tastypie.spec ++++++
--- /var/tmp/diff_new_pack.PQac9b/_old 2022-02-26 17:02:44.351542156 +0100
+++ /var/tmp/diff_new_pack.PQac9b/_new 2022-02-26 17:02:44.359542158 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-django-tastypie
#
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,14 +18,12 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-django-tastypie
-Version: 0.14.3
+Version: 0.14.4
Release: 0
Summary: A webservice API framework layer for Django
License: BSD-3-Clause
URL: https://github.com/django-tastypie/django-tastypie
Source:
https://github.com/django-tastypie/django-tastypie/archive/v%{version}.tar.gz
-# PATCH-FIX-UPSTREAM merged_pr_1624_chunk.patch -- based on PR 1624
-Patch0: merged_pr_1624_chunk.patch
BuildRequires: %{python_module Django >= 1.11.0}
BuildRequires: %{python_module PyYAML}
BuildRequires: %{python_module biplist}
@@ -53,7 +51,8 @@
%prep
%setup -q -n django-tastypie-%{version}
-%patch0 -p1
+%autopatch -p1
+
# https://github.com/django-tastypie/django-tastypie/issues/1617
sed -Ei
's/(test_apikey_and_authentication_enforce_user|test_is_authenticated)/_\1/'
tests/core/tests/authentication.py
@@ -67,16 +66,16 @@
%check
# The tests are doing what is specified in tox.ini
%{python_expand export PYTHONPATH=${PWD}:${PWD}/tests/
-django-admin.py-%{$python_bin_suffix} test -p '*' core.tests
--settings=settings_core
-django-admin.py-%{$python_bin_suffix} test basic.tests
--settings=settings_basic
-django-admin.py-%{$python_bin_suffix} test related_resource.tests
--settings=settings_related
-django-admin.py-%{$python_bin_suffix} test alphanumeric.tests
--settings=settings_alphanumeric
-django-admin.py-%{$python_bin_suffix} test authorization.tests
--settings=settings_authorization
-django-admin.py-%{$python_bin_suffix} test content_gfk.tests
--settings=settings_content_gfk
-django-admin.py-%{$python_bin_suffix} test customuser.tests
--settings=settings_customuser
-django-admin.py-%{$python_bin_suffix} test namespaced.tests
--settings=settings_namespaced
-django-admin.py-%{$python_bin_suffix} test slashless.tests
--settings=settings_slashless
-django-admin.py-%{$python_bin_suffix} test validation.tests
--settings=settings_validation
+django-admin-%{$python_bin_suffix} test -v 3 -p '*' core.tests
--settings=settings_core
+django-admin-%{$python_bin_suffix} test -v 3 basic.tests
--settings=settings_basic
+django-admin-%{$python_bin_suffix} test -v 3 related_resource.tests
--settings=settings_related
+django-admin-%{$python_bin_suffix} test -v 3 alphanumeric.tests
--settings=settings_alphanumeric
+django-admin-%{$python_bin_suffix} test -v 3 authorization.tests
--settings=settings_authorization
+django-admin-%{$python_bin_suffix} test -v 3 content_gfk.tests
--settings=settings_content_gfk
+django-admin-%{$python_bin_suffix} test -v 3 customuser.tests
--settings=settings_customuser
+django-admin-%{$python_bin_suffix} test -v 3 namespaced.tests
--settings=settings_namespaced
+django-admin-%{$python_bin_suffix} test -v 3 slashless.tests
--settings=settings_slashless
+django-admin-%{$python_bin_suffix} test -v 3 validation.tests
--settings=settings_validation
}
%files %{python_files}
++++++ v0.14.3.tar.gz -> v0.14.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/django-tastypie-0.14.3/.github/workflows/python-package.yml
new/django-tastypie-0.14.4/.github/workflows/python-package.yml
--- old/django-tastypie-0.14.3/.github/workflows/python-package.yml
1970-01-01 01:00:00.000000000 +0100
+++ new/django-tastypie-0.14.4/.github/workflows/python-package.yml
2022-01-04 02:18:10.000000000 +0100
@@ -0,0 +1,59 @@
+# This workflow will install Python dependencies, run tests and lint with a
variety of Python versions
+# For more information see:
https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
+
+name: Test Matrix
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
+ django-version: ["2.2", "3.2", "4.0"] # Todo: add "dev" back
+ exclude:
+ - python-version: "3.6"
+ django-version: "4.0"
+# - python-version: "3.6"
+# django-version: "dev"
+ - python-version: "3.7"
+ django-version: "4.0"
+# - python-version: "3.7"
+# django-version: "dev"
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install OS dependencies
+ run: |
+ sudo apt install -y binutils libproj-dev gdal-bin
libsqlite3-mod-spatialite
+
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip wheel virtualenv tox coveralls
+ - name: Erase cached coverage
+ run: |
+ coverage erase
+ - name: Flake8
+ run: |
+ tox -e py${{matrix.python-version}}-flake8
+ - name: Docs
+ run: |
+ tox -e py${{matrix.python-version}}-docs
+ - name: Test with Tox
+ run: |
+ tox -e py${{matrix.python-version}}-dj${{matrix.django-version}}
+ - name: Upload coverage data to coveralls.io
+ run: coveralls --service=github
+ continue-on-error: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/.travis.yml
new/django-tastypie-0.14.4/.travis.yml
--- old/django-tastypie-0.14.3/.travis.yml 2020-01-06 15:43:54.000000000
+0100
+++ new/django-tastypie-0.14.4/.travis.yml 1970-01-01 01:00:00.000000000
+0100
@@ -1,68 +0,0 @@
-sudo: false
-dist: bionic
-
-language: python
-
-python:
- - "2.7"
- - "3.5"
- - "3.6"
- - "3.7"
-
-env:
- - MODE=flake8
- - MODE=flake8-strict
- - MODE=docs
- - DJANGO_VERSION=dj111
- - DJANGO_VERSION=dj22
- - DJANGO_VERSION=dj30
- - DJANGO_VERSION=djdev
-
-matrix:
- allow_failures:
- - env: DJANGO_VERSION=djdev
- - env: MODE=flake8-strict
- exclude:
- - python: "2.7"
- env: DJANGO_VERSION=djdev
- - python: "2.7"
- env: DJANGO_VERSION=dj22
- - python: "2.7"
- env: DJANGO_VERSION=dj30
- - python: "3.5"
- env: DJANGO_VERSION=dj30
- - python: "3.5"
- env: DJANGO_VERSION=djdev
-
-before_install:
- - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 762E3157
-
-addons:
- apt:
- packages:
- - binutils
- - libproj-dev
- - gdal-bin
- - libsqlite3-mod-spatialite
-
-cache:
- directories:
- - $HOME/.cache/pip
-
-before_cache:
- - rm -f $HOME/.cache/pip/log/debug.log
-
-# command to install dependencies
-install:
- - pip install -U pip
- - pip install -U wheel virtualenv
- - pip install tox coveralls
-
-after_success:
- - coveralls
-
-# command to run tests
-script:
- - apt list --installed
- - coverage erase
- - tox -e py${TRAVIS_PYTHON_VERSION/./}-${DJANGO_VERSION}${MODE}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/README.rst
new/django-tastypie-0.14.4/README.rst
--- old/django-tastypie-0.14.3/README.rst 2020-01-06 15:43:54.000000000
+0100
+++ new/django-tastypie-0.14.4/README.rst 2022-01-04 02:18:10.000000000
+0100
@@ -6,8 +6,8 @@
:target: https://django-tastypie.readthedocs.io/
:alt: Docs
-.. image::
https://travis-ci.org/django-tastypie/django-tastypie.svg?branch=master
- :target: https://travis-ci.org/django-tastypie/django-tastypie
+.. image::
https://github.com/django-tastypie/django-tastypie/actions/workflows/python-package.yml/badge.svg
+ :target: https://github.com/django-tastypie/django-tastypie/actions
:alt: CI
.. image::
https://coveralls.io/repos/django-tastypie/django-tastypie/badge.svg?service=github
@@ -34,8 +34,8 @@
Core
----
-* Python 2.7+ or Python 3.4+ (Whatever is supported by your version of Django)
-* Django 1.11, 2.2 (LTS releases) or Django 3.0 (latest release)
+* Python 3.6+, preferably 3.8+ (Whatever is supported by your version of
Django)
+* Django 2.2, 3.2 (LTS releases) or Django 4.0 (latest release)
* dateutil (http://labix.org/python-dateutil) >= 2.1
Format Support
@@ -71,7 +71,7 @@
# urls.py
# =======
- from django.conf.urls import url, include
+ from django.urls.conf import re_path, include
from tastypie.api import Api
from myapp.api import EntryResource
@@ -80,7 +80,7 @@
urlpatterns = [
# The normal jazz here then...
- url(r'^api/', include(v1_api.urls)),
+ re_path(r'^api/', include(v1_api.urls)),
]
That gets you a fully working, read-write API for the ``Entry`` model that
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/api.rst
new/django-tastypie-0.14.4/docs/api.rst
--- old/django-tastypie-0.14.3/docs/api.rst 2020-01-06 15:43:54.000000000
+0100
+++ new/django-tastypie-0.14.4/docs/api.rst 2022-01-04 02:18:10.000000000
+0100
@@ -17,7 +17,7 @@
A sample api definition might look something like (usually located in a
URLconf)::
- from django.conf.urls import url, include
+ from django.urls.conf import re_path, include
from tastypie.api import Api
from myapp.api.resources import UserResource, EntryResource
@@ -27,7 +27,7 @@
# Standard bits...
urlpatterns = [
- url(r'^api/', include(v1_api.urls)),
+ re_path(r'^api/', include(v1_api.urls)),
]
For namespaced urls see :ref:`namespaces`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/code/myproject/urls.py
new/django-tastypie-0.14.4/docs/code/myproject/urls.py
--- old/django-tastypie-0.14.3/docs/code/myproject/urls.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/docs/code/myproject/urls.py 2022-01-04
02:18:10.000000000 +0100
@@ -1,4 +1,4 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
from django.contrib import admin
urlpatterns = [
@@ -6,5 +6,5 @@
# url(r'^$', 'myproject.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
- url(r'^admin/', include(admin.site.urls)),
+ re_path(r'^admin/', include(admin.site.urls)),
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/cookbook.rst
new/django-tastypie-0.14.4/docs/cookbook.rst
--- old/django-tastypie-0.14.3/docs/cookbook.rst 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/docs/cookbook.rst 2022-01-04
02:18:10.000000000 +0100
@@ -242,7 +242,7 @@
.. testcode::
# myapp/api/resources.py
- from django.conf.urls import url
+ from django.urls.conf import re_path
from django.contrib.auth.models import User
@@ -253,7 +253,7 @@
def prepend_urls(self):
return [
- url(r"^(?P<resource_name>%s)/(?P<username>[\w\d_.-]+)/$" %
self._meta.resource_name, self.wrap_view('dispatch_detail'),
name="api_dispatch_detail"),
+ re_path(r"^(?P<resource_name>%s)/(?P<username>[\w\d_.-]+)/$" %
self._meta.resource_name, self.wrap_view('dispatch_detail'),
name="api_dispatch_detail"),
]
.. testoutput::
@@ -285,13 +285,13 @@
return super(MyModelResource, self).dispatch(request_type,
request, **kwargs)
# urls.py
- from django.conf.urls import url, include
+ from django.urls.conf import re_path, include
mymodel_resource = MyModelResource()
urlpatterns = [
# The normal jazz here, then...
- url(r'^api/(?P<username>\w+)/', include(mymodel_resource.urls)),
+ re_path(r'^api/(?P<username>\w+)/', include(mymodel_resource.urls)),
]
.. testoutput::
@@ -320,7 +320,7 @@
def prepend_urls(self):
return [
- url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/children%s$" %
(self._meta.resource_name, trailing_slash()), self.wrap_view('get_children'),
name="api_get_children"),
+
re_path(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/children%s$" %
(self._meta.resource_name, trailing_slash()), self.wrap_view('get_children'),
name="api_get_children"),
]
def get_children(self, request, **kwargs):
@@ -350,7 +350,7 @@
We leave the CRUD methods of the resource alone, choosing to add a new endpoint
at ``/api/v1/notes/search/``::
- from django.conf.urls import url, include
+ from django.urls.conf import re_path, include
from django.core.paginator import Paginator, InvalidPage
from django.http import Http404
from haystack.query import SearchQuerySet
@@ -366,7 +366,7 @@
def prepend_urls(self):
return [
- url(r"^(?P<resource_name>%s)/search%s$" %
(self._meta.resource_name, trailing_slash()), self.wrap_view('get_search'),
name="api_get_search"),
+ re_path(r"^(?P<resource_name>%s)/search%s$" %
(self._meta.resource_name, trailing_slash()), self.wrap_view('get_search'),
name="api_get_search"),
]
def get_search(self, request, **kwargs):
@@ -560,10 +560,10 @@
the response format as a file extension, e.g. /api/v1/users.json
"""
return [
- url(r"^(?P<resource_name>%s)\.(?P<format>\w+)$" %
self._meta.resource_name, self.wrap_view('dispatch_list'),
name="api_dispatch_list"),
- url(r"^(?P<resource_name>%s)/schema\.(?P<format>\w+)$" %
self._meta.resource_name, self.wrap_view('get_schema'), name="api_get_schema"),
-
url(r"^(?P<resource_name>%s)/set/(?P<pk_list>\w[\w/;-]*)\.(?P<format>\w+)$" %
self._meta.resource_name, self.wrap_view('get_multiple'),
name="api_get_multiple"),
-
url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)\.(?P<format>\w+)$" %
self._meta.resource_name, self.wrap_view('dispatch_detail'),
name="api_dispatch_detail"),
+ re_path(r"^(?P<resource_name>%s)\.(?P<format>\w+)$" %
self._meta.resource_name, self.wrap_view('dispatch_list'),
name="api_dispatch_list"),
+ re_path(r"^(?P<resource_name>%s)/schema\.(?P<format>\w+)$" %
self._meta.resource_name, self.wrap_view('get_schema'), name="api_get_schema"),
+
re_path(r"^(?P<resource_name>%s)/set/(?P<pk_list>\w[\w/;-]*)\.(?P<format>\w+)$"
% self._meta.resource_name, self.wrap_view('get_multiple'),
name="api_get_multiple"),
+
re_path(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)\.(?P<format>\w+)$" %
self._meta.resource_name, self.wrap_view('dispatch_detail'),
name="api_dispatch_detail"),
]
def determine_format(self, request):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/index.rst
new/django-tastypie-0.14.4/docs/index.rst
--- old/django-tastypie-0.14.3/docs/index.rst 2020-01-06 15:43:54.000000000
+0100
+++ new/django-tastypie-0.14.4/docs/index.rst 2022-01-04 02:18:10.000000000
+0100
@@ -61,7 +61,7 @@
4. In your root URLconf, add the following code (around where the admin code
might be)::
- from django.conf.urls import url, include
+ from django.urls.conf import re_path, include
from tastypie.api import Api
from my_app.api.resources import MyModelResource
@@ -71,7 +71,7 @@
urlpatterns = [
# ...more URLconf bits here...
# Then add:
- url(r'^api/', include(v1_api.urls)),
+ re_path(r'^api/', include(v1_api.urls)),
]
5. Hit http://localhost:8000/api/v1/?format=json in your browser!
@@ -83,8 +83,8 @@
Core
----
-* Python 2.7+ or Python 3.4+ (Whatever is supported by your version of Django)
-* Django 1.11, 2.2 (LTS releases) or Django 3.0 (latest release)
+* Python 3.6+, preferably 3.8+ (Whatever is supported by your version of
Django)
+* Django 2.2, 3.2 (LTS releases) or Django 4.0 (latest release)
* dateutil (http://labix.org/python-dateutil) >= 2.1
Format Support
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/interacting.rst
new/django-tastypie-0.14.4/docs/interacting.rst
--- old/django-tastypie-0.14.3/docs/interacting.rst 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/docs/interacting.rst 2022-01-04
02:18:10.000000000 +0100
@@ -45,7 +45,7 @@
# urls.py
- from django.conf.urls import url, include
+ from django.urls.conf import re_path, include
from tastypie.api import Api
from myapp.api.resources import EntryResource, UserResource
@@ -55,8 +55,8 @@
urlpatterns = [
# The normal jazz here...
- url(r'^blog/', include('myapp.urls')),
- url(r'^api/', include(v1_api.urls)),
+ re_path(r'^blog/', include('myapp.urls')),
+ re_path(r'^api/', include(v1_api.urls)),
]
Let's fire up a shell & start exploring the API!
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/namespaces.rst
new/django-tastypie-0.14.4/docs/namespaces.rst
--- old/django-tastypie-0.14.3/docs/namespaces.rst 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/docs/namespaces.rst 2022-01-04
02:18:10.000000000 +0100
@@ -8,7 +8,7 @@
A sample definition of your API in this case would be something like::
- from django.conf.urls import url, include
+ from django.urls.conf import re_path, include
from tastypie.api import NamespacedApi
from my_application.api.resources import NamespacedUserResource
@@ -16,7 +16,7 @@
api.register(NamespacedUserResource())
urlpatterns = [
- url(r'^api/', include(api.urls, namespace='special')),
+ re_path(r'^api/', include(api.urls, namespace='special')),
]
And your model resource::
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/release_notes/index.rst
new/django-tastypie-0.14.4/docs/release_notes/index.rst
--- old/django-tastypie-0.14.3/docs/release_notes/index.rst 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/docs/release_notes/index.rst 2022-01-04
02:18:10.000000000 +0100
@@ -5,6 +5,7 @@
:maxdepth: 1
dev
+ v0.14.4
v0.14.3
v0.14.2
v0.14.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/django-tastypie-0.14.3/docs/release_notes/v0.14.4.rst
new/django-tastypie-0.14.4/docs/release_notes/v0.14.4.rst
--- old/django-tastypie-0.14.3/docs/release_notes/v0.14.4.rst 1970-01-01
01:00:00.000000000 +0100
+++ new/django-tastypie-0.14.4/docs/release_notes/v0.14.4.rst 2022-01-04
02:18:10.000000000 +0100
@@ -0,0 +1,9 @@
+v0.14.4
+=======
+
+:date: 2022-01-03
+
+Added support for Django 4.0.
+Drops explicit support for Django 3.0, 3.1 (non-LTS).
+Drops all support for Python 2.
+Fixes a TZ bug in date-formatted Retry-After responses from throttling
revealed by Django 4.0's switch to Zoneinfo.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/tutorial.rst
new/django-tastypie-0.14.4/docs/tutorial.rst
--- old/django-tastypie-0.14.3/docs/tutorial.rst 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/docs/tutorial.rst 2022-01-04
02:18:10.000000000 +0100
@@ -131,15 +131,15 @@
``urls``::
# urls.py
- from django.conf.urls import url, include
+ from django.urls.conf import re_path, include
from myapp.api import EntryResource
entry_resource = EntryResource()
urlpatterns = [
# The normal jazz here...
- url(r'^blog/', include('myapp.urls')),
- url(r'^api/', include(entry_resource.urls)),
+ re_path(r'^blog/', include('myapp.urls')),
+ re_path(r'^api/', include(entry_resource.urls)),
]
Now it's just a matter of firing up server (``./manage.py runserver``) and
@@ -258,7 +258,7 @@
following::
# urls.py
- from django.conf.urls import url, include
+ from django.urls.conf import re_path, include
from tastypie.api import Api
from myapp.api import EntryResource, UserResource
@@ -268,8 +268,8 @@
urlpatterns = [
# The normal jazz here...
- url(r'^blog/', include('myapp.urls')),
- url(r'^api/', include(v1_api.urls)),
+ re_path(r'^blog/', include('myapp.urls')),
+ re_path(r'^api/', include(v1_api.urls)),
]
Note that we're now creating an :class:`~tastypie.api.Api` instance,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tastypie/__init__.py
new/django-tastypie-0.14.4/tastypie/__init__.py
--- old/django-tastypie-0.14.3/tastypie/__init__.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tastypie/__init__.py 2022-01-04
02:18:10.000000000 +0100
@@ -3,7 +3,7 @@
__author__ = 'Daniel Lindsley & the Tastypie core team'
-VERSION = (0, 14, 3)
+VERSION = (0, 14, 4)
__short_version__ = '.'.join(map(str, VERSION[0:2]))
__version__ = ''.join(['.'.join(map(str, VERSION[0:3])), ''.join(VERSION[3:])])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tastypie/api.py
new/django-tastypie-0.14.4/tastypie/api.py
--- old/django-tastypie-0.14.3/tastypie/api.py 2020-01-06 15:43:54.000000000
+0100
+++ new/django-tastypie-0.14.4/tastypie/api.py 2022-01-04 02:18:10.000000000
+0100
@@ -1,6 +1,5 @@
from __future__ import unicode_literals
import warnings
-from django.conf.urls import url, include
from django.core.exceptions import ImproperlyConfigured
from django.http import HttpResponse, HttpResponseBadRequest
from tastypie.compat import reverse
@@ -9,6 +8,7 @@
from tastypie.utils import is_valid_jsonp_callback_value, string_to_python,
trailing_slash
from tastypie.utils.mime import determine_format, build_content_type
from tastypie.resources import Resource
+from django.urls.conf import re_path, include
class Api(object):
@@ -103,12 +103,12 @@
``Resources`` beneath it.
"""
pattern_list = [
- url(r"^(?P<api_name>%s)%s$" % (self.api_name, trailing_slash),
self.wrap_view('top_level'), name="api_%s_top_level" % self.api_name),
+ re_path(r"^(?P<api_name>%s)%s$" % (self.api_name, trailing_slash),
self.wrap_view('top_level'), name="api_%s_top_level" % self.api_name),
]
for name in sorted(self._registry.keys()):
self._registry[name].api_name = self.api_name
- pattern_list.append(url(r"^(?P<api_name>%s)/" % self.api_name,
include(self._registry[name].urls)))
+ pattern_list.append(re_path(r"^(?P<api_name>%s)/" % self.api_name,
include(self._registry[name].urls)))
urlpatterns = self.prepend_urls()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tastypie/authentication.py
new/django-tastypie-0.14.4/tastypie/authentication.py
--- old/django-tastypie-0.14.3/tastypie/authentication.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tastypie/authentication.py 2022-01-04
02:18:10.000000000 +0100
@@ -9,13 +9,13 @@
from django.conf import settings
from django.contrib.auth import authenticate
from django.core.exceptions import ImproperlyConfigured
-from django.middleware.csrf import _sanitize_token, constant_time_compare
-from django.utils.translation import ugettext as _
+from django.middleware.csrf import _sanitize_token
+from django.utils.translation import gettext as _
from six.moves.urllib.parse import urlparse
from tastypie.compat import (
- get_user_model, get_username_field, unsalt_token, is_authenticated
+ get_user_model, get_username_field, compare_sanitized_tokens,
InvalidTokenFormat
)
from tastypie.http import HttpUnauthorized
@@ -306,10 +306,10 @@
# the serialized bodies.
if request.method in ('GET', 'HEAD', 'OPTIONS', 'TRACE'):
- return is_authenticated(request.user)
+ return request.user.is_authenticated
if getattr(request, '_dont_enforce_csrf_checks', False):
- return is_authenticated(request.user)
+ return request.user.is_authenticated
csrf_token =
_sanitize_token(request.COOKIES.get(settings.CSRF_COOKIE_NAME, ''))
@@ -325,13 +325,15 @@
return False
request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')
- request_csrf_token = _sanitize_token(request_csrf_token)
+ try:
+ request_csrf_token = _sanitize_token(request_csrf_token)
+ except InvalidTokenFormat:
+ return False
- if not constant_time_compare(unsalt_token(request_csrf_token),
- unsalt_token(csrf_token)):
+ if not compare_sanitized_tokens(request_csrf_token, csrf_token):
return False
- return is_authenticated(request.user)
+ return request.user.is_authenticated
def get_identifier(self, request):
"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tastypie/compat.py
new/django-tastypie-0.14.4/tastypie/compat.py
--- old/django-tastypie-0.14.3/tastypie/compat.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tastypie/compat.py 2022-01-04
02:18:10.000000000 +0100
@@ -13,16 +13,6 @@
AUTH_USER_MODEL = settings.AUTH_USER_MODEL
-def is_authenticated(user):
- """
- Django is changing User.is_authenticated into a property. Calling it
- will be deprecated by Django 2.0 and a warning in 1.10+.
- """
- if django.VERSION < (1, 10):
- return bool(user.is_authenticated())
- return bool(user.is_authenticated)
-
-
def get_username_field():
return get_user_model().USERNAME_FIELD
@@ -31,21 +21,16 @@
return meta.model_name
-atomic_decorator = django.db.transaction.atomic
-
-# Compatability for salted vs unsalted CSRF tokens;
-# Django 1.10's _sanitize_token also hashes it, so it can't be compared
directly.
-# Solution is to call _sanitize_token on both tokens, then unsalt or noop both
-try:
- from django.middleware.csrf import _unsalt_cipher_token
-
- def unsalt_token(token):
- return _unsalt_cipher_token(token)
-except ImportError:
+def is_ajax(request):
+ """
+ Handle multiple ways of detecting an ajax request. Probably nearly
useless.
+ """
+ if hasattr(request, 'is_ajax'):
+ return request.is_ajax()
+ return request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
- def unsalt_token(token):
- return token
+atomic_decorator = django.db.transaction.atomic
# force_text deprecated in 2.2, removed in 3.0
# note that in 1.1.x, force_str and force_text both exist, but force_str
behaves
@@ -54,3 +39,38 @@
from django.utils.encoding import force_text as force_str # noqa
else:
from django.utils.encoding import force_str # noqa
+
+
+compare_sanitized_tokens = None
+
+# django 4.0
+try:
+ from django.middleware.csrf import _does_token_match, InvalidTokenFormat
+ compare_sanitized_tokens = _does_token_match
+except ImportError:
+ pass
+
+
+# django 3.2
+if compare_sanitized_tokens is None:
+ try:
+ from django.middleware.csrf import _compare_masked_tokens
+ compare_sanitized_tokens = _compare_masked_tokens
+ class InvalidTokenFormat(Exception): # noqa
+ pass
+ except ImportError:
+ pass
+
+# django 2.2
+if compare_sanitized_tokens is None:
+ try:
+ from django.middleware.csrf import _unsalt_cipher_token,
constant_time_compare
+
+ def compare_sanitized_tokens(request_csrf_token, csrf_token):
+ return
constant_time_compare(_unsalt_cipher_token(request_csrf_token),
+ _unsalt_cipher_token(csrf_token))
+
+ class InvalidTokenFormat(Exception): # noqa
+ pass
+ except ImportError: # pragma: no cover
+ raise ImportError("Couldn't find a way to compare csrf tokens safely")
# pragma: no cover
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tastypie/resources.py
new/django-tastypie-0.14.4/tastypie/resources.py
--- old/django-tastypie-0.14.3/tastypie/resources.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tastypie/resources.py 2022-01-04
02:18:10.000000000 +0100
@@ -10,13 +10,14 @@
from wsgiref.handlers import format_date_time
from django.conf import settings
-from django.conf.urls import url
from django.core.exceptions import (
ObjectDoesNotExist, MultipleObjectsReturned, ValidationError,
FieldDoesNotExist
)
from django.core.signals import got_request_exception
from django.core.exceptions import ImproperlyConfigured
from django.db.models.fields.related import ForeignKey
+from django.urls.conf import re_path
+from tastypie.utils.timezone import make_naive_utc
try:
from django.contrib.gis.db.models.fields import GeometryField
except (ImproperlyConfigured, ImportError):
@@ -40,7 +41,7 @@
from tastypie.authorization import ReadOnlyAuthorization
from tastypie.bundle import Bundle
from tastypie.cache import NoCache
-from tastypie.compat import NoReverseMatch, reverse, Resolver404,
get_script_prefix
+from tastypie.compat import NoReverseMatch, reverse, Resolver404,
get_script_prefix, is_ajax
from tastypie.constants import ALL, ALL_WITH_RELATIONS
from tastypie.exceptions import (
NotFound, BadRequest, InvalidFilterError, HydrationError, InvalidSortError,
@@ -240,7 +241,7 @@
# ``Cache-Control`` available then patch the header.
patch_cache_control(response,
**self._meta.cache.cache_control())
- if request.is_ajax() and not
response.has_header("Cache-Control"):
+ if is_ajax(request) and not
response.has_header("Cache-Control"):
# IE excessively caches XMLHttpRequests, so we're disabling
# the browser cache here.
# See http://www.enhanceie.com/ie/bugs.asp for details.
@@ -338,10 +339,10 @@
The standard URLs this ``Resource`` should respond to.
"""
return [
- url(r"^(?P<resource_name>%s)%s$" % (self._meta.resource_name,
trailing_slash), self.wrap_view('dispatch_list'), name="api_dispatch_list"),
- url(r"^(?P<resource_name>%s)/schema%s$" %
(self._meta.resource_name, trailing_slash), self.wrap_view('get_schema'),
name="api_get_schema"),
- url(r"^(?P<resource_name>%s)/set/(?P<%s_list>.*?)%s$" %
(self._meta.resource_name, self._meta.detail_uri_name, trailing_slash),
self.wrap_view('get_multiple'), name="api_get_multiple"),
- url(r"^(?P<resource_name>%s)/(?P<%s>.*?)%s$" %
(self._meta.resource_name, self._meta.detail_uri_name, trailing_slash),
self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
+ re_path(r"^(?P<resource_name>%s)%s$" % (self._meta.resource_name,
trailing_slash), self.wrap_view('dispatch_list'), name="api_dispatch_list"),
+ re_path(r"^(?P<resource_name>%s)/schema%s$" %
(self._meta.resource_name, trailing_slash), self.wrap_view('get_schema'),
name="api_get_schema"),
+ re_path(r"^(?P<resource_name>%s)/set/(?P<%s_list>.*?)%s$" %
(self._meta.resource_name, self._meta.detail_uri_name, trailing_slash),
self.wrap_view('get_multiple'), name="api_get_multiple"),
+ re_path(r"^(?P<resource_name>%s)/(?P<%s>.*?)%s$" %
(self._meta.resource_name, self._meta.detail_uri_name, trailing_slash),
self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
]
def override_urls(self):
@@ -602,7 +603,9 @@
if isinstance(throttle, int) and not isinstance(throttle, bool):
response['Retry-After'] = throttle
elif isinstance(throttle, datetime):
- response['Retry-After'] =
format_date_time(mktime(throttle.timetuple()))
+ # change to UTC (GMT) and make naive, to avoid wsgiref also
doing an implicit TZ conversion
+ throttle_utc = make_naive_utc(throttle)
+ response['Retry-After'] =
format_date_time(mktime(throttle_utc.timetuple()))
raise ImmediateHttpResponse(response=response)
@@ -1910,7 +1913,7 @@
result = fields.FloatField
elif internal_type in ('DecimalField',):
result = fields.DecimalField
- elif internal_type in ('IntegerField', 'PositiveIntegerField',
'PositiveSmallIntegerField', 'SmallIntegerField', 'AutoField',
'BigIntegerField'):
+ elif internal_type in ('IntegerField', 'PositiveIntegerField',
'PositiveSmallIntegerField', 'SmallIntegerField', 'AutoField',
'BigIntegerField', 'BigAutoField'):
result = fields.IntegerField
elif internal_type in ('FileField', 'ImageField'):
result = fields.FileField
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tastypie/utils/timezone.py
new/django-tastypie-0.14.4/tastypie/utils/timezone.py
--- old/django-tastypie-0.14.3/tastypie/utils/timezone.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tastypie/utils/timezone.py 2022-01-04
02:18:10.000000000 +0100
@@ -19,6 +19,15 @@
return value
+def make_naive_utc(value):
+ """
+ Translate a datetime to UTC, then strip TZ info; useful as a last step
before creating the
+ Retry-After header.
+ """
+ utc_value = timezone.localtime(value, timezone.utc)
+ return timezone.make_naive(utc_value)
+
+
def now():
d = timezone.now()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/alphanumeric/urls.py
new/django-tastypie-0.14.4/tests/alphanumeric/urls.py
--- old/django-tastypie-0.14.3/tests/alphanumeric/urls.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/alphanumeric/urls.py 2022-01-04
02:18:10.000000000 +0100
@@ -1,6 +1,6 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
urlpatterns = [
- url(r'^api/', include('alphanumeric.api.urls')),
+ re_path(r'^api/', include('alphanumeric.api.urls')),
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/authorization/urls.py
new/django-tastypie-0.14.4/tests/authorization/urls.py
--- old/django-tastypie-0.14.3/tests/authorization/urls.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/authorization/urls.py 2022-01-04
02:18:10.000000000 +0100
@@ -1,4 +1,4 @@
-from django.conf.urls import url, include
+from django.urls.conf import include, re_path
from tastypie.api import Api
@@ -12,5 +12,5 @@
v1_api.register(UserResource())
urlpatterns = [
- url(r'^api/', include(v1_api.urls)),
+ re_path(r'^api/', include(v1_api.urls)),
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/basic/urls.py
new/django-tastypie-0.14.4/tests/basic/urls.py
--- old/django-tastypie-0.14.3/tests/basic/urls.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/basic/urls.py 2022-01-04
02:18:10.000000000 +0100
@@ -1,6 +1,6 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
urlpatterns = [
- url(r'^api/', include('basic.api.urls')),
+ re_path(r'^api/', include('basic.api.urls')),
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/content_gfk/urls.py
new/django-tastypie-0.14.4/tests/content_gfk/urls.py
--- old/django-tastypie-0.14.3/tests/content_gfk/urls.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/content_gfk/urls.py 2022-01-04
02:18:10.000000000 +0100
@@ -1,6 +1,6 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
urlpatterns = [
- url(r'^api/', include('content_gfk.api.urls')),
+ re_path(r'^api/', include('content_gfk.api.urls')),
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/django-tastypie-0.14.3/tests/core/migrations/0001_initial.py
new/django-tastypie-0.14.4/tests/core/migrations/0001_initial.py
--- old/django-tastypie-0.14.3/tests/core/migrations/0001_initial.py
2020-01-06 15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/core/migrations/0001_initial.py
2022-01-04 02:18:10.000000000 +0100
@@ -114,4 +114,10 @@
],
bases=('core.note',),
),
+ migrations.CreateModel(
+ name='BigAutoNowModel',
+ fields=[
+ ('id', models.BigAutoField(primary_key=True, serialize=False,
verbose_name='ID')),
+ ],
+ ),
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/core/models.py
new/django-tastypie-0.14.4/tests/core/models.py
--- old/django-tastypie-0.14.3/tests/core/models.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/core/models.py 2022-01-04
02:18:10.000000000 +0100
@@ -97,6 +97,13 @@
app_label = 'core'
+class BigAutoNowModel(models.Model):
+ id = models.BigAutoField(primary_key=True)
+
+ class Meta:
+ app_label = 'core'
+
+
class Counter(models.Model):
name = models.CharField(max_length=30)
slug = models.SlugField(unique=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/core/tests/__init__.py
new/django-tastypie-0.14.4/tests/core/tests/__init__.py
--- old/django-tastypie-0.14.3/tests/core/tests/__init__.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/core/tests/__init__.py 2022-01-04
02:18:10.000000000 +0100
@@ -1,6 +1,6 @@
+import doctest
import warnings
warnings.simplefilter('ignore', Warning) # noqa
-import doctest
from core.tests.api import * # noqa
from core.tests.authentication import * # noqa
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/core/tests/api_urls.py
new/django-tastypie-0.14.4/tests/core/tests/api_urls.py
--- old/django-tastypie-0.14.3/tests/core/tests/api_urls.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/core/tests/api_urls.py 2022-01-04
02:18:10.000000000 +0100
@@ -1,4 +1,4 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
from core.tests.api import Api, NoteResource, UserResource
@@ -8,5 +8,5 @@
api.register(UserResource())
urlpatterns = [
- url(r'^api/', include(api.urls)),
+ re_path(r'^api/', include(api.urls)),
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/django-tastypie-0.14.3/tests/core/tests/manual_urls.py
new/django-tastypie-0.14.4/tests/core/tests/manual_urls.py
--- old/django-tastypie-0.14.3/tests/core/tests/manual_urls.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/core/tests/manual_urls.py 2022-01-04
02:18:10.000000000 +0100
@@ -1,9 +1,9 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
from core.tests.resources import NoteResource
note_resource = NoteResource()
urlpatterns = [
- url(r'^', include(note_resource.urls)),
+ re_path(r'^', include(note_resource.urls)),
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/django-tastypie-0.14.3/tests/core/tests/resource_urls.py
new/django-tastypie-0.14.4/tests/core/tests/resource_urls.py
--- old/django-tastypie-0.14.3/tests/core/tests/resource_urls.py
2020-01-06 15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/core/tests/resource_urls.py
2022-01-04 02:18:10.000000000 +0100
@@ -1,4 +1,4 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
from django.contrib.auth.models import User
from tastypie import fields
from tastypie.resources import ModelResource
@@ -33,5 +33,5 @@
api.register(SubjectResource())
urlpatterns = [
- url(r'^api/', include(api.urls)),
+ re_path(r'^api/', include(api.urls)),
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/core/tests/resources.py
new/django-tastypie-0.14.4/tests/core/tests/resources.py
--- old/django-tastypie-0.14.3/tests/core/tests/resources.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/core/tests/resources.py 2022-01-04
02:18:10.000000000 +0100
@@ -18,6 +18,7 @@
from django.core.cache import cache
from django.core.exceptions import FieldError, MultipleObjectsReturned,
ObjectDoesNotExist, ImproperlyConfigured
from django.core import mail
+from time import mktime
try:
from django.urls import reverse
except ImportError:
@@ -36,7 +37,7 @@
UnsupportedSerializationFormat, UnsupportedDeserializationFormat,
)
from tastypie import fields, http
-from tastypie.compat import is_authenticated, force_str
+from tastypie.compat import force_str
from tastypie.paginator import Paginator
from tastypie.resources import (
ALL, ALL_WITH_RELATIONS, convert_post_to_put, convert_post_to_patch,
@@ -49,7 +50,7 @@
from core.models import (
Note, NoteWithEditor, Subject, MediaBit, AutoNowNote, DateRecord, Counter,
- MyDefaultPKModel, MyUUIDModel, MyRelatedUUIDModel,
+ MyDefaultPKModel, MyUUIDModel, MyRelatedUUIDModel, BigAutoNowModel,
)
from core.tests.mocks import MockRequest
from core.utils import adjust_schema, SimpleHandler
@@ -1056,6 +1057,19 @@
return '/api/v1/autonownotes/%s/' % bundle_or_obj.obj.id
+class BigAutoNowModelResource(ModelResource):
+ class Meta:
+ resource_name = 'bigautonowmodels'
+ queryset = BigAutoNowModel.objects.all()
+ authorization = Authorization()
+
+ def get_resource_uri(self, bundle_or_obj=None,
url_name='api_dispatch_list'):
+ if bundle_or_obj is None:
+ return '/api/v1/bigautonowmodels/'
+
+ return '/api/v1/bigautonowmodels/%s/' % bundle_or_obj.obj.id
+
+
class CustomPaginator(Paginator):
def page(self):
data = super(CustomPaginator, self).page()
@@ -1338,7 +1352,7 @@
class PerUserAuthorization(Authorization):
def read_list(self, object_list, bundle):
if bundle.request and hasattr(bundle.request, 'user'):
- if is_authenticated(bundle.request.user):
+ if bundle.request.user.is_authenticated:
object_list = object_list.filter(author=bundle.request.user)
else:
object_list = object_list.none()
@@ -1661,6 +1675,20 @@
self.assertEqual(annr.fields['updated'].readonly, False)
self.assertEqual(annr.fields['updated'].unique, False)
+ def test_big_auto_field(self):
+ annr = BigAutoNowModelResource()
+ self.assertEqual(len(annr.fields), 2)
+ self.assertEqual(sorted(annr.fields.keys()), ['id', 'resource_uri'])
+
+ self.assertTrue(isinstance(annr.fields['id'], fields.IntegerField))
+ self.assertEqual(annr.fields['id'].attribute, 'id')
+ self.assertEqual(annr.fields['id'].blank, True)
+ self.assertEqual(annr.fields['id']._default, '')
+ self.assertEqual(annr.fields['id'].instance_name, 'id')
+ self.assertEqual(annr.fields['id'].null, False)
+ self.assertEqual(annr.fields['id'].readonly, False)
+ self.assertEqual(annr.fields['id'].unique, True)
+
def test_invalid_model_resource(self):
"""
Test error message regarding ModelResource lacking object_class and
queryset.
@@ -4156,10 +4184,71 @@
@patch('tastypie.throttle.time')
@override_settings(DEBUG=False)
def test_check_datetime_throttling(self, mocked_time):
- mocked_time.time.return_value = time.time()
retry_after = datetime.datetime(year=2014, month=8, day=8, hour=8,
minute=55, tzinfo=timezone.utc)
- retry_after_str = 'Fri, 08 Aug 2014 14:55:00 GMT'
+ mocked_time.time.return_value = mktime(retry_after.timetuple())
+ retry_after_str = 'Fri, 08 Aug 2014 08:55:00 GMT'
+
+ resource = ThrottledNoteResource()
+ _orginal_throttle = resource._meta.throttle
+
+ class DatetimeThrottle(resource._meta.throttle.__class__):
+ def should_be_throttled(self, *args, **kwargs):
+ ret = super(DatetimeThrottle, self).should_be_throttled(*args,
**kwargs)
+ if ret:
+ return retry_after
+ return False
+ resource._meta.throttle = DatetimeThrottle(
+ throttle_at=resource._meta.throttle.throttle_at,
+ timeframe=resource._meta.throttle.timeframe,
+ expiration=resource._meta.throttle.expiration
+ )
+
+ request = HttpRequest()
+ request.GET = {'format': 'json'}
+ request.method = 'GET'
+
+ # Not throttled.
+ resp = resource.dispatch('list', request)
+ self.assertEqual(resp.status_code, 200)
+ self.assertEqual(len(cache.get('noaddr_nohost_accesses')), 1)
+
+ # Not throttled.
+ resp = resource.dispatch('list', request)
+ self.assertEqual(resp.status_code, 200)
+ self.assertEqual(len(cache.get('noaddr_nohost_accesses')), 2)
+
+ # Throttled.
+ with self.assertRaises(ImmediateHttpResponse) as ctx:
+ resp = resource.dispatch('list', request)
+ e = ctx.exception
+ self.assertEqual(e.response.status_code, 429)
+ self.assertEqual(e.response['Retry-After'], retry_after_str)
+ self.assertEqual(len(cache.get('noaddr_nohost_accesses')), 2)
+
+ # Throttled.
+ with self.assertRaises(ImmediateHttpResponse) as ctx:
+ resp = resource.dispatch('list', request)
+ e = ctx.exception
+ self.assertEqual(e.response.status_code, 429)
+ self.assertEqual(e.response['Retry-After'], retry_after_str)
+ self.assertEqual(len(cache.get('noaddr_nohost_accesses')), 2)
+
+ # Check the ``wrap_view``.
+ resp = resource.wrap_view('dispatch_list')(request)
+ self.assertEqual(resp.status_code, 429)
+ self.assertEqual(resp['Retry-After'], retry_after_str)
+ self.assertEqual(len(cache.get('noaddr_nohost_accesses')), 2)
+
+ resource._meta.throttle = _orginal_throttle
+
+ @patch('tastypie.throttle.time')
+ @override_settings(DEBUG=False, USE_TZ=False)
+ def test_check_datetime_throttling_notz(self, mocked_time):
+
+ retry_after = datetime.datetime(year=2014, month=8, day=8, hour=8,
minute=55, tzinfo=timezone.utc)
+ mocked_time.time.return_value = mktime(retry_after.timetuple())
+ retry_after_str = 'Fri, 08 Aug 2014 08:55:00 GMT'
resource = ThrottledNoteResource()
_orginal_throttle = resource._meta.throttle
@@ -4937,7 +5026,7 @@
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.content.decode('utf-8'), '{"content": "This is
my very first post using my shiny new API. Pretty sweet, huh?", "created":
"2010-03-30T20:05:00", "id": 1, "is_active": true, "resource_uri":
"/api/v1/notes/1/", "slug": "first-post", "title": "First Post!", "updated":
"2010-03-30T20:05:00"}')
self.assertTrue(resp.has_header('Cache-Control'))
- self.assertEqual(resp._headers['cache-control'], ('Cache-Control',
'no-cache'))
+ self.assertEqual(resp['Cache-Control'], 'no-cache')
# Now as Ajax.
request.META = {'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'}
@@ -4945,7 +5034,7 @@
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.content.decode('utf-8'), '{"content": "This is
my very first post using my shiny new API. Pretty sweet, huh?", "created":
"2010-03-30T20:05:00", "id": 1, "is_active": true, "resource_uri":
"/api/v1/notes/1/", "slug": "first-post", "title": "First Post!", "updated":
"2010-03-30T20:05:00"}')
self.assertTrue(resp.has_header('cache-control'))
- self.assertEqual(resp._headers['cache-control'], ('Cache-Control',
'no-cache'))
+ self.assertEqual(resp['Cache-Control'], 'no-cache')
def test_custom_paginator(self):
mock_request = MockRequest()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/gis/urls.py
new/django-tastypie-0.14.4/tests/gis/urls.py
--- old/django-tastypie-0.14.3/tests/gis/urls.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/gis/urls.py 2022-01-04
02:18:10.000000000 +0100
@@ -1,6 +1,6 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
urlpatterns = [
- url(r'^api/', include('gis.api.urls')),
+ re_path(r'^api/', include('gis.api.urls')),
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/namespaced/api/urls.py
new/django-tastypie-0.14.4/tests/namespaced/api/urls.py
--- old/django-tastypie-0.14.3/tests/namespaced/api/urls.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/namespaced/api/urls.py 2022-01-04
02:18:10.000000000 +0100
@@ -1,5 +1,5 @@
from django.conf import settings
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
from tastypie.api import NamespacedApi
from namespaced.api.resources import NamespacedNoteResource,
NamespacedUserResource
@@ -14,5 +14,5 @@
included = include(api.urls, namespace='special')
urlpatterns = [
- url(r'^api/', included),
+ re_path(r'^api/', included),
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/profilingtests/urls.py
new/django-tastypie-0.14.4/tests/profilingtests/urls.py
--- old/django-tastypie-0.14.3/tests/profilingtests/urls.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/profilingtests/urls.py 2022-01-04
02:18:10.000000000 +0100
@@ -1,4 +1,4 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
from tastypie.api import Api
@@ -10,5 +10,5 @@
api.register(UserResource())
urlpatterns = [
- url(r'^api/', include(api.urls)),
+ re_path(r'^api/', include(api.urls)),
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/requirements.txt
new/django-tastypie-0.14.4/tests/requirements.txt
--- old/django-tastypie-0.14.3/tests/requirements.txt 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/requirements.txt 2022-01-04
02:18:10.000000000 +0100
@@ -4,5 +4,5 @@
defusedxml
lxml
mock<1.1.0
-pytz==2013b0
+pytz==2021.1
PyYAML
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/settings.py
new/django-tastypie-0.14.4/tests/settings.py
--- old/django-tastypie-0.14.3/tests/settings.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/settings.py 2022-01-04
02:18:10.000000000 +0100
@@ -38,6 +38,7 @@
'NAME': DATABASE_NAME,
}
}
+DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
ALLOWED_HOSTS = ['example.com']
@@ -91,3 +92,5 @@
if DJANGO_VERSION >= DJANGO_20:
MIDDLEWARE.remove('django.contrib.auth.middleware.SessionAuthenticationMiddleware')
+
+SECURE_REFERRER_POLICY = None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/slashless/api/urls.py
new/django-tastypie-0.14.4/tests/slashless/api/urls.py
--- old/django-tastypie-0.14.3/tests/slashless/api/urls.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/slashless/api/urls.py 2022-01-04
02:18:10.000000000 +0100
@@ -1,4 +1,4 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
from tastypie.api import Api
from slashless.api.resources import NoteResource, UserResource
@@ -8,5 +8,5 @@
api.register(UserResource(), canonical=True)
urlpatterns = [
- url(r'^api/', include(api.urls)),
+ re_path(r'^api/', include(api.urls)),
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/validation/api/urls.py
new/django-tastypie-0.14.4/tests/validation/api/urls.py
--- old/django-tastypie-0.14.3/tests/validation/api/urls.py 2020-01-06
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/validation/api/urls.py 2022-01-04
02:18:10.000000000 +0100
@@ -1,4 +1,4 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
from tastypie.api import Api
@@ -12,5 +12,5 @@
api.register(AnnotatedNoteResource(), canonical=True)
urlpatterns = [
- url(r'^api/', include(api.urls)),
+ re_path(r'^api/', include(api.urls)),
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/django-tastypie-0.14.3/tox.ini
new/django-tastypie-0.14.4/tox.ini
--- old/django-tastypie-0.14.3/tox.ini 2020-01-06 15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tox.ini 2022-01-04 02:18:10.000000000 +0100
@@ -1,32 +1,33 @@
[tox]
envlist =
- py{27}-dj{111}
- py{36,37}-dj{22,30,dev}
- py{27,37}-docs,
- py{27,37}-flake8,
- py{27,37}-flake8-strict
+ py{3.6,3.7,3.8,3.9,3.10}-dj{2.2,3.2}
+ py{3.8,3.9,3.10}-dj{4.0,dev}
+ py{3.6,3.7,3.8,3.9,3.10}-docs,
+ py{3.6,3.7,3.8,3.9,3.10}-flake8,
+ py{3.8,3.9,3.10}-flake8-strict
skipsdist=True
[testenv]
usedevelop=True
-test-executable =
- {envbindir}/coverage run --append --source=tastypie,tests
{envbindir}/django-admin.py
setenv =
PYTHONPATH = {toxinidir}:{toxinidir}/tests
PYTHONWARNINGS = always
+ TESTEXE = {envbindir}/coverage run --append --source=tastypie,tests
{envbindir}/django-admin.py
+ dj{4.0,dev}: TESTEXE = {envbindir}/coverage run --append
--source=tastypie,tests {envbindir}/django-admin
+
commands =
- dj{111,22,30,dev}: {[testenv]test-executable} test -p '*' core.tests
--settings=settings_core
- dj{111,22,30,dev}: {[testenv]test-executable} test basic.tests
--settings=settings_basic
- dj{111,22,30,dev}: {[testenv]test-executable} test related_resource.tests
--settings=settings_related
- dj{111,22,30,dev}: {[testenv]test-executable} test alphanumeric.tests
--settings=settings_alphanumeric
- dj{111,22,30,dev}: {[testenv]test-executable} test authorization.tests
--settings=settings_authorization
- dj{111,22,30,dev}: {[testenv]test-executable} test content_gfk.tests
--settings=settings_content_gfk
- dj{111,22,30,dev}: {[testenv]test-executable} test customuser.tests
--settings=settings_customuser
- dj{111,22,30,dev}: {[testenv]test-executable} test namespaced.tests
--settings=settings_namespaced
- dj{111,22,30,dev}: {[testenv]test-executable} test slashless.tests
--settings=settings_slashless
- dj{111,22,30,dev}: {[testenv]test-executable} test validation.tests
--settings=settings_validation
- dj{111,22,30,dev}: {[testenv]test-executable} test gis.tests
--settings=settings_gis_spatialite
+ dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test -p '*' core.tests
--settings=settings_core
+ dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test basic.tests
--settings=settings_basic
+ dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test related_resource.tests
--settings=settings_related
+ dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test alphanumeric.tests
--settings=settings_alphanumeric
+ dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test authorization.tests
--settings=settings_authorization
+ dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test content_gfk.tests
--settings=settings_content_gfk
+ dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test customuser.tests
--settings=settings_customuser
+ dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test namespaced.tests
--settings=settings_namespaced
+ dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test slashless.tests
--settings=settings_slashless
+ dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test validation.tests
--settings=settings_validation
+ dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test gis.tests
--settings=settings_gis_spatialite
docs: sphinx-build -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html
docs: sphinx-build -W -b doctest -d {envtmpdir}/doctrees . {envtmpdir}/html
@@ -35,27 +36,23 @@
flake8-strict: {envbindir}/flake8 --ignore=E128 --max-complexity 10 .
basepython =
- py27: python2.7
- py35: python3.5
- py36: python3.6
- py37: python3.7
+ py3.6: python3.6
+ py3.7: python3.7
+ py3.8: python3.8
+ py3.9: python3.9
+ py3.10: python3.10
deps =
- dj111: Django>=1.11,<1.12
- dj22: Django>=2.2,<2.3
- dj30: Django>=3.0,<3.1
- djdev: https://github.com/django/django/archive/master.tar.gz
-
- py27-dj{111}: django-oauth-plus==2.2.9
- py27-dj{111}: python-digest
- py27-dj{111}: oauth2
- py27-dj{111}: pysqlite
- py{35,36,37}-dj{111,22,30,dev}: python3-digest>=1.8b4
- dj{111,22,30,dev}: -r{toxinidir}/tests/requirements.txt
+ dj2.2: Django>=2.2,<2.3
+ dj3.2: Django>=3.2,<3.3
+ dj4.0: Django>=4.0,<4.1
+ djdev: https://github.com/django/django/archive/refs/heads/main.zip
+
+ dj{2.2,3.2,4.0,dev}: python3-digest>=1.8b4
+ dj{2.2,3.2,4.0,dev}: -r{toxinidir}/tests/requirements.txt
+ py{3.6,3.7}-docs: Django~=2.2
+ py{3.7,3.8,3.9,3.10}-docs: Django<4.1
docs: Sphinx
- py27-docs: Django<2.0
- py35-docs: Django<3.0
- py{36,37}-docs: Django<3.1
docs: mock
docs: sphinx_rtd_theme