This commit is contained in:
Asif Saif Uddin (Auvi) 2020-05-12 10:04:01 +06:00
commit c32997735e
19 changed files with 42 additions and 29 deletions

View File

@ -1,6 +1,6 @@
language: python
cache: pip
dist: xenial
dist: bionic
matrix:
fast_finish: true
include:

View File

@ -89,7 +89,7 @@ Startup up a new project like so...
Now edit the `example/urls.py` module in your project:
```python
from django.conf.urls import url, include
from django.urls import path, include
from django.contrib.auth.models import User
from rest_framework import serializers, viewsets, routers
@ -114,8 +114,8 @@ router.register(r'users', UserViewSet)
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
```

View File

@ -304,7 +304,7 @@ If successfully authenticated, `RemoteUserAuthentication` provides the following
Consult your web server's documentation for information about configuring an authentication method, e.g.:
* [Apache Authentication How-To](https://httpd.apache.org/docs/2.4/howto/auth.html)
* [NGINX (Restricting Access)](https://www.nginx.com/resources/admin-guide/#restricting_access)
* [NGINX (Restricting Access)](https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/)
# Custom authentication

View File

@ -71,7 +71,7 @@ If you have specific requirements for creating schema endpoints that are accesse
For example, the following additional route could be used on a viewset to provide a linkable schema endpoint.
@action(methods=['GET'], detail=False)
def schema(self, request):
def api_schema(self, request):
meta = self.metadata_class()
data = meta.determine_metadata(request, self)
return Response(data)

View File

@ -148,7 +148,7 @@ Don't forget to make sure you've also added `rest_framework` to your `INSTALLED_
We're ready to create our API now.
Here's our project's root `urls.py` module:
from django.conf.urls import url, include
from django.urls import path, include
from django.contrib.auth.models import User
from rest_framework import routers, serializers, viewsets
@ -170,8 +170,8 @@ Here's our project's root `urls.py` module:
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
You can now open the API in your browser at [http://127.0.0.1:8000/](http://127.0.0.1:8000/), and view your new 'users' API. If you use the login control in the top right corner you'll also be able to add, create and delete users from the system.

View File

@ -1,6 +1,6 @@
# PEP8 code linting, which we run on all commits.
flake8==3.7.8
flake8-tidy-imports==3.0.0
flake8==3.7.9
flake8-tidy-imports==4.1.0
pycodestyle==2.5.0
# Sort and lint imports

View File

@ -1,2 +1,2 @@
# MkDocs to build our documentation.
mkdocs==1.0.4
mkdocs==1.1

View File

@ -1,8 +1,8 @@
# Optional packages which may be used with REST framework.
psycopg2-binary>=2.8.2, <2.9
psycopg2-binary>=2.8.5, <2.9
markdown==3.1.1
pygments==2.4.2
django-guardian==2.1.0
django-guardian==2.2.0
django-filter>=2.2.0, <2.3
coreapi==2.3.1
coreschema==0.0.4

View File

@ -1,8 +1,8 @@
# Wheel for PyPI installs.
wheel==0.30.0
wheel==0.34.2
# Twine for secured PyPI uploads.
twine==1.11.0
twine==3.1.1
# Transifex client for managing translation resources.
transifex-client==0.11
transifex-client==0.13.9

View File

@ -1,4 +1,4 @@
# Pytest for running the tests.
pytest>=5.0,<5.1
pytest-django>=3.5.1,<3.6
pytest>=5.4.1,<5.5
pytest-django>=3.9.0,<3.10
pytest-cov>=2.7.1

View File

@ -3,10 +3,8 @@ from django.contrib import admin
from rest_framework.authtoken.models import Token
@admin.register(Token)
class TokenAdmin(admin.ModelAdmin):
list_display = ('key', 'user', 'created')
fields = ('user',)
ordering = ('-created',)
admin.site.register(Token, TokenAdmin)

View File

@ -85,7 +85,7 @@ class SearchFilter(BaseFilterBackend):
search_field = search_field[1:]
# Annotated fields do not need to be distinct
if isinstance(queryset, models.QuerySet) and search_field in queryset.query.annotations:
return False
continue
parts = search_field.split(LOOKUP_SEP)
for part in parts:
field = opts.get_field(part)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -250,7 +250,7 @@
csrfToken: "{{ csrf_token }}"
};
</script>
<script src="{% static "rest_framework/js/jquery-3.4.1.min.js" %}"></script>
<script src="{% static "rest_framework/js/jquery-3.5.1.min.js" %}"></script>
<script src="{% static "rest_framework/js/ajax-form.js" %}"></script>
<script src="{% static "rest_framework/js/csrf.js" %}"></script>
<script src="{% static "rest_framework/js/bootstrap.min.js" %}"></script>

View File

@ -293,7 +293,7 @@
csrfToken: "{% if request %}{{ csrf_token }}{% endif %}"
};
</script>
<script src="{% static "rest_framework/js/jquery-3.4.1.min.js" %}"></script>
<script src="{% static "rest_framework/js/jquery-3.5.1.min.js" %}"></script>
<script src="{% static "rest_framework/js/ajax-form.js" %}"></script>
<script src="{% static "rest_framework/js/csrf.js" %}"></script>
<script src="{% static "rest_framework/js/bootstrap.min.js" %}"></script>

View File

@ -66,6 +66,6 @@ at <code>rest_framework/docs/error.html</code>.</p>
<script src="{% static 'rest_framework/js/jquery-3.4.1.min.js' %}"></script>
<script src="{% static 'rest_framework/js/jquery-3.5.1.min.js' %}"></script>
</body>
</html>

View File

@ -38,7 +38,7 @@
{% include "rest_framework/docs/auth/basic.html" %}
{% include "rest_framework/docs/auth/session.html" %}
<script src="{% static 'rest_framework/js/jquery-3.4.1.min.js' %}"></script>
<script src="{% static 'rest_framework/js/jquery-3.5.1.min.js' %}"></script>
<script src="{% static 'rest_framework/js/bootstrap.min.js' %}"></script>
<script src="{% static 'rest_framework/docs/js/jquery.json-view.min.js' %}"></script>
<script src="{% static 'rest_framework/docs/js/api.js' %}"></script>

View File

@ -406,6 +406,21 @@ class SearchFilterAnnotatedFieldTests(TestCase):
assert len(response.data) == 1
assert response.data[0]['title_text'] == 'ABCDEF'
def test_must_call_distinct_subsequent_m2m_fields(self):
f = filters.SearchFilter()
queryset = SearchFilterModelM2M.objects.annotate(
title_text=Upper(
Concat(models.F('title'), models.F('text'))
)
).all()
# Sanity check that m2m must call distinct
assert f.must_call_distinct(queryset, ['attributes'])
# Annotated field should not prevent m2m must call distinct
assert f.must_call_distinct(queryset, ['title_text', 'attributes'])
class OrderingFilterModel(models.Model):
title = models.CharField(max_length=20, verbose_name='verbose title')