mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-08 06:14:47 +03:00
Merge remote-tracking branch 'reference/master' into feature/deprecated
This commit is contained in:
commit
cbee382590
|
@ -31,4 +31,4 @@ script:
|
|||
|
||||
after_success:
|
||||
- pip install codecov
|
||||
- codecov
|
||||
- codecov -e TOX_ENV
|
||||
|
|
|
@ -57,7 +57,7 @@ Note that setting a `default` value implies that the field is not required. Incl
|
|||
|
||||
### `source`
|
||||
|
||||
The name of the attribute that will be used to populate the field. May be a method that only takes a `self` argument, such as `URLField('get_absolute_url')`, or may use dotted notation to traverse attributes, such as `EmailField(source='user.email')`.
|
||||
The name of the attribute that will be used to populate the field. May be a method that only takes a `self` argument, such as `URLField(source='get_absolute_url')`, or may use dotted notation to traverse attributes, such as `EmailField(source='user.email')`.
|
||||
|
||||
The value `source='*'` has a special meaning, and is used to indicate that the entire object should be passed through to the field. This can be useful for creating nested representations, or for fields which require access to the complete object in order to determine the output representation.
|
||||
|
||||
|
|
|
@ -287,7 +287,7 @@ Similarly if a nested representation should be a list of items, you should pass
|
|||
|
||||
## Writable nested representations
|
||||
|
||||
When dealing with nested representations that support deserializing the data, an errors with nested objects will be nested under the field name of the nested object.
|
||||
When dealing with nested representations that support deserializing the data, any errors with nested objects will be nested under the field name of the nested object.
|
||||
|
||||
serializer = CommentSerializer(data={'user': {'email': 'foobar', 'username': 'doe'}, 'content': 'baz'})
|
||||
serializer.is_valid()
|
||||
|
@ -356,7 +356,7 @@ It is possible that a third party package, providing automatic support some kind
|
|||
|
||||
#### Handling saving related instances in model manager classes
|
||||
|
||||
An alternative to saving multiple related instances in the serializer is to write custom model manager classes handle creating the correct instances.
|
||||
An alternative to saving multiple related instances in the serializer is to write custom model manager classes that handle creating the correct instances.
|
||||
|
||||
For example, suppose we wanted to ensure that `User` instances and `Profile` instances are always created together as a pair. We might write a custom manager class that looks something like this:
|
||||
|
||||
|
@ -478,7 +478,7 @@ For example:
|
|||
model = Account
|
||||
fields = '__all__'
|
||||
|
||||
You can set the `exclude` attribute of the to a list of fields to be excluded from the serializer.
|
||||
You can set the `exclude` attribute to a list of fields to be excluded from the serializer.
|
||||
|
||||
For example:
|
||||
|
||||
|
@ -551,7 +551,7 @@ Please review the [Validators Documentation](/api-guide/validators/) for details
|
|||
|
||||
## Additional keyword arguments
|
||||
|
||||
There is also a shortcut allowing you to specify arbitrary additional keyword arguments on fields, using the `extra_kwargs` option. Similarly to `read_only_fields` this means you do not need to explicitly declare the field on the serializer.
|
||||
There is also a shortcut allowing you to specify arbitrary additional keyword arguments on fields, using the `extra_kwargs` option. As in the case of `read_only_fields`, this means you do not need to explicitly declare the field on the serializer.
|
||||
|
||||
This option is a dictionary, mapping field names to a dictionary of keyword arguments. For example:
|
||||
|
||||
|
@ -832,7 +832,7 @@ This class implements the same basic API as the `Serializer` class:
|
|||
* `.data` - Returns the outgoing primitive representation.
|
||||
* `.is_valid()` - Deserializes and validates incoming data.
|
||||
* `.validated_data` - Returns the validated incoming data.
|
||||
* `.errors` - Returns an errors during validation.
|
||||
* `.errors` - Returns any errors during validation.
|
||||
* `.save()` - Persists the validated data into an object instance.
|
||||
|
||||
There are four methods that can be overridden, depending on what functionality you want the serializer class to support:
|
||||
|
|
|
@ -72,7 +72,7 @@ The following settings keys are also used to control versioning:
|
|||
|
||||
* `DEFAULT_VERSION`. The value that should be used for `request.version` when no versioning information is present. Defaults to `None`.
|
||||
* `ALLOWED_VERSIONS`. If set, this value will restrict the set of versions that may be returned by the versioning scheme, and will raise an error if the provided version if not in this set. Note that the value used for the `DEFAULT_VERSION` setting is always considered to be part of the `ALLOWED_VERSIONS` set. Defaults to `None`.
|
||||
* `VERSION_PARAMETER`. The string that should used for any versioning parameters, such as in the media type or URL query parameters. Defaults to `'version'`.
|
||||
* `VERSION_PARAM`. The string that should used for any versioning parameters, such as in the media type or URL query parameters. Defaults to `'version'`.
|
||||
|
||||
You can also set your versioning class plus those three values on a per-view or a per-viewset basis by defining your own versioning scheme and using the `default_version`, `allowed_versions` and `version_param` class variables. For example, if you want to use `URLPathVersioning`:
|
||||
|
||||
|
|
|
@ -237,6 +237,7 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque
|
|||
|
||||
### Misc
|
||||
|
||||
* [cookiecutter-django-rest][cookiecutter-django-rest] - A cookiecutter template that takes care of the setup and configuration so you can focus on making your REST apis awesome.
|
||||
* [djangorestrelationalhyperlink][djangorestrelationalhyperlink] - A hyperlinked serialiser that can can be used to alter relationships via hyperlinks, but otherwise like a hyperlink model serializer.
|
||||
* [django-rest-swagger][django-rest-swagger] - An API documentation generator for Swagger UI.
|
||||
* [django-rest-framework-proxy][django-rest-framework-proxy] - Proxy to redirect incoming request to another API server.
|
||||
|
@ -346,4 +347,5 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque
|
|||
[django-rest-framework-braces]: https://github.com/dealertrack/django-rest-framework-braces
|
||||
[dry-rest-permissions]: https://github.com/Helioscene/dry-rest-permissions
|
||||
[django-url-filter]: https://github.com/miki725/django-url-filter
|
||||
[cookiecutter-django-rest]: https://github.com/agconti/cookiecutter-django-rest
|
||||
[drf-haystack]: http://drf-haystack.readthedocs.org/en/latest/
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
|
||||
try:
|
||||
from django.contrib.auth import get_user_model
|
||||
except ImportError: # django < 1.5
|
||||
from django.contrib.auth.models import User
|
||||
else:
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding model 'Token'
|
||||
db.create_table('authtoken_token', (
|
||||
('key', self.gf('django.db.models.fields.CharField')(max_length=40, primary_key=True)),
|
||||
('user', self.gf('django.db.models.fields.related.OneToOneField')(related_name='auth_token', unique=True, to=orm['%s.%s' % (User._meta.app_label, User._meta.object_name)])),
|
||||
('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
|
||||
))
|
||||
db.send_create_signal('authtoken', ['Token'])
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'Token'
|
||||
db.delete_table('authtoken_token')
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
"%s.%s" % (User._meta.app_label, User._meta.module_name): {
|
||||
'Meta': {'object_name': User._meta.module_name, 'db_table': repr(User._meta.db_table)},
|
||||
},
|
||||
'authtoken.token': {
|
||||
'Meta': {'object_name': 'Token'},
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'primary_key': 'True'}),
|
||||
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'auth_token'", 'unique': 'True', 'to': "orm['%s.%s']" % (User._meta.app_label, User._meta.object_name)})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['authtoken']
|
|
@ -111,6 +111,7 @@ except ImportError:
|
|||
# Fixes (#1712). We keep the try/except for the test suite.
|
||||
guardian = None
|
||||
try:
|
||||
if 'guardian' in settings.INSTALLED_APPS:
|
||||
import guardian
|
||||
import guardian.shortcuts # Fixes #1624
|
||||
except ImportError:
|
||||
|
|
|
@ -30,10 +30,10 @@ def _force_text_recursive(data):
|
|||
return ReturnList(ret, serializer=data.serializer)
|
||||
return data
|
||||
elif isinstance(data, dict):
|
||||
ret = dict([
|
||||
(key, _force_text_recursive(value))
|
||||
ret = {
|
||||
key: _force_text_recursive(value)
|
||||
for key, value in data.items()
|
||||
])
|
||||
}
|
||||
if isinstance(data, ReturnDict):
|
||||
return ReturnDict(ret, serializer=data.serializer)
|
||||
return data
|
||||
|
|
|
@ -604,8 +604,8 @@ class BooleanField(Field):
|
|||
}
|
||||
default_empty_html = False
|
||||
initial = False
|
||||
TRUE_VALUES = set(('t', 'T', 'true', 'True', 'TRUE', '1', 1, True))
|
||||
FALSE_VALUES = set(('f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False))
|
||||
TRUE_VALUES = {'t', 'T', 'true', 'True', 'TRUE', '1', 1, True}
|
||||
FALSE_VALUES = {'f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
assert 'allow_null' not in kwargs, '`allow_null` is not a valid option. Use `NullBooleanField` instead.'
|
||||
|
@ -634,9 +634,9 @@ class NullBooleanField(Field):
|
|||
'invalid': _('"{input}" is not a valid boolean.')
|
||||
}
|
||||
initial = None
|
||||
TRUE_VALUES = set(('t', 'T', 'true', 'True', 'TRUE', '1', 1, True))
|
||||
FALSE_VALUES = set(('f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False))
|
||||
NULL_VALUES = set(('n', 'N', 'null', 'Null', 'NULL', '', None))
|
||||
TRUE_VALUES = {'t', 'T', 'true', 'True', 'TRUE', '1', 1, True}
|
||||
FALSE_VALUES = {'f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False}
|
||||
NULL_VALUES = {'n', 'N', 'null', 'Null', 'NULL', '', None}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
assert 'allow_null' not in kwargs, '`allow_null` is not a valid option.'
|
||||
|
@ -1241,9 +1241,9 @@ class ChoiceField(Field):
|
|||
# Map the string representation of choices to the underlying value.
|
||||
# Allows us to deal with eg. integer choices while supporting either
|
||||
# integer or string input, but still get the correct datatype out.
|
||||
self.choice_strings_to_values = dict([
|
||||
(six.text_type(key), key) for key in self.choices.keys()
|
||||
])
|
||||
self.choice_strings_to_values = {
|
||||
six.text_type(key): key for key in self.choices.keys()
|
||||
}
|
||||
|
||||
self.allow_blank = kwargs.pop('allow_blank', False)
|
||||
|
||||
|
@ -1302,15 +1302,15 @@ class MultipleChoiceField(ChoiceField):
|
|||
if not self.allow_empty and len(data) == 0:
|
||||
self.fail('empty')
|
||||
|
||||
return set([
|
||||
return {
|
||||
super(MultipleChoiceField, self).to_internal_value(item)
|
||||
for item in data
|
||||
])
|
||||
}
|
||||
|
||||
def to_representation(self, value):
|
||||
return set([
|
||||
return {
|
||||
self.choice_strings_to_values.get(six.text_type(item), item) for item in value
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
class FilePathField(ChoiceField):
|
||||
|
@ -1508,19 +1508,19 @@ class DictField(Field):
|
|||
data = html.parse_html_dict(data)
|
||||
if not isinstance(data, dict):
|
||||
self.fail('not_a_dict', input_type=type(data).__name__)
|
||||
return dict([
|
||||
(six.text_type(key), self.child.run_validation(value))
|
||||
return {
|
||||
six.text_type(key): self.child.run_validation(value)
|
||||
for key, value in data.items()
|
||||
])
|
||||
}
|
||||
|
||||
def to_representation(self, value):
|
||||
"""
|
||||
List of object instances -> List of dicts of primitive datatypes.
|
||||
"""
|
||||
return dict([
|
||||
(six.text_type(key), self.child.to_representation(val))
|
||||
return {
|
||||
six.text_type(key): self.child.to_representation(val)
|
||||
for key, val in value.items()
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
class JSONField(Field):
|
||||
|
|
|
@ -77,7 +77,7 @@ class SimpleMetadata(BaseMetadata):
|
|||
the fields that are accepted for 'PUT' and 'POST' methods.
|
||||
"""
|
||||
actions = {}
|
||||
for method in set(['PUT', 'POST']) & set(view.allowed_methods):
|
||||
for method in {'PUT', 'POST'} & set(view.allowed_methods):
|
||||
view.request = clone_request(request, method)
|
||||
try:
|
||||
# Test global permissions
|
||||
|
|
|
@ -79,11 +79,7 @@ def _get_displayed_page_numbers(current, final):
|
|||
|
||||
# We always include the first two pages, last two pages, and
|
||||
# two pages either side of the current page.
|
||||
included = set((
|
||||
1,
|
||||
current - 1, current, current + 1,
|
||||
final
|
||||
))
|
||||
included = {1, current - 1, current, current + 1, final}
|
||||
|
||||
# If the break would only exclude a single page number then we
|
||||
# may as well include the page number instead of the break.
|
||||
|
|
|
@ -174,7 +174,7 @@ class SimpleRouter(BaseRouter):
|
|||
url_path = initkwargs.pop("url_path", None) or methodname
|
||||
ret.append(Route(
|
||||
url=replace_methodname(route.url, url_path),
|
||||
mapping=dict((httpmethod, methodname) for httpmethod in httpmethods),
|
||||
mapping={httpmethod: methodname for httpmethod in httpmethods},
|
||||
name=replace_methodname(route.name, url_path),
|
||||
initkwargs=initkwargs,
|
||||
))
|
||||
|
|
|
@ -125,10 +125,10 @@ class BaseSerializer(Field):
|
|||
}
|
||||
if allow_empty is not None:
|
||||
list_kwargs['allow_empty'] = allow_empty
|
||||
list_kwargs.update(dict([
|
||||
(key, value) for key, value in kwargs.items()
|
||||
list_kwargs.update({
|
||||
key: value for key, value in kwargs.items()
|
||||
if key in LIST_SERIALIZER_KWARGS
|
||||
]))
|
||||
})
|
||||
meta = getattr(cls, 'Meta', None)
|
||||
list_serializer_class = getattr(meta, 'list_serializer_class', ListSerializer)
|
||||
return list_serializer_class(*args, **list_kwargs)
|
||||
|
@ -305,10 +305,10 @@ def get_validation_error_detail(exc):
|
|||
elif isinstance(exc.detail, dict):
|
||||
# If errors may be a dict we use the standard {key: list of values}.
|
||||
# Here we ensure that all the values are *lists* of errors.
|
||||
return dict([
|
||||
(key, value if isinstance(value, list) else [value])
|
||||
return {
|
||||
key: value if isinstance(value, list) else [value]
|
||||
for key, value in exc.detail.items()
|
||||
])
|
||||
}
|
||||
elif isinstance(exc.detail, list):
|
||||
# Errors raised as a list are non-field errors.
|
||||
return {
|
||||
|
@ -1237,13 +1237,10 @@ class ModelSerializer(Serializer):
|
|||
|
||||
for model_field in model_fields.values():
|
||||
# Include each of the `unique_for_*` field names.
|
||||
unique_constraint_names |= set([
|
||||
model_field.unique_for_date,
|
||||
model_field.unique_for_month,
|
||||
model_field.unique_for_year
|
||||
])
|
||||
unique_constraint_names |= {model_field.unique_for_date, model_field.unique_for_month,
|
||||
model_field.unique_for_year}
|
||||
|
||||
unique_constraint_names -= set([None])
|
||||
unique_constraint_names -= {None}
|
||||
|
||||
# Include each of the `unique_together` field names,
|
||||
# so long as all the field names are included on the serializer.
|
||||
|
@ -1357,10 +1354,10 @@ class ModelSerializer(Serializer):
|
|||
# which may map onto a model field. Any dotted field name lookups
|
||||
# cannot map to a field, and must be a traversal, so we're not
|
||||
# including those.
|
||||
field_names = set([
|
||||
field_names = {
|
||||
field.source for field in self.fields.values()
|
||||
if (field.source != '*') and ('.' not in field.source)
|
||||
])
|
||||
}
|
||||
|
||||
# Note that we make sure to check `unique_together` both on the
|
||||
# base model class, but also on any parent classes.
|
||||
|
|
|
@ -219,7 +219,7 @@
|
|||
{% endif %}
|
||||
|
||||
{% block script %}
|
||||
<script src="{% static "rest_framework/js/jquery-1.11.3-min.js" %}"></script>
|
||||
<script src="{% static "rest_framework/js/jquery-1.11.3.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>
|
||||
|
|
|
@ -123,7 +123,8 @@ def get_field_kwargs(field_name, model_field):
|
|||
# Ensure that max_length is passed explicitly as a keyword arg,
|
||||
# rather than as a validator.
|
||||
max_length = getattr(model_field, 'max_length', None)
|
||||
if max_length is not None and isinstance(model_field, models.CharField):
|
||||
if max_length is not None and (isinstance(model_field, models.CharField) or
|
||||
isinstance(model_field, models.TextField)):
|
||||
kwargs['max_length'] = max_length
|
||||
validator_kwarg = [
|
||||
validator for validator in validator_kwarg
|
||||
|
|
|
@ -100,11 +100,11 @@ class UniqueTogetherValidator(object):
|
|||
if self.instance is not None:
|
||||
return
|
||||
|
||||
missing = dict([
|
||||
(field_name, self.missing_message)
|
||||
missing = {
|
||||
field_name: self.missing_message
|
||||
for field_name in self.fields
|
||||
if field_name not in attrs
|
||||
])
|
||||
}
|
||||
if missing:
|
||||
raise ValidationError(missing)
|
||||
|
||||
|
@ -120,10 +120,10 @@ class UniqueTogetherValidator(object):
|
|||
attrs[field_name] = getattr(self.instance, field_name)
|
||||
|
||||
# Determine the filter keyword arguments and filter the queryset.
|
||||
filter_kwargs = dict([
|
||||
(field_name, attrs[field_name])
|
||||
filter_kwargs = {
|
||||
field_name: attrs[field_name]
|
||||
for field_name in self.fields
|
||||
])
|
||||
}
|
||||
return queryset.filter(**filter_kwargs)
|
||||
|
||||
def exclude_current_instance(self, attrs, queryset):
|
||||
|
@ -184,11 +184,11 @@ class BaseUniqueForValidator(object):
|
|||
The `UniqueFor<Range>Validator` classes always force an implied
|
||||
'required' state on the fields they are applied to.
|
||||
"""
|
||||
missing = dict([
|
||||
(field_name, self.missing_message)
|
||||
missing = {
|
||||
field_name: self.missing_message
|
||||
for field_name in [self.field, self.date_field]
|
||||
if field_name not in attrs
|
||||
])
|
||||
}
|
||||
if missing:
|
||||
raise ValidationError(missing)
|
||||
|
||||
|
|
|
@ -93,7 +93,11 @@ if __name__ == "__main__":
|
|||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
pytest_args = ['--cov', 'rest_framework'] + pytest_args
|
||||
pytest_args = [
|
||||
'--cov-report',
|
||||
'xml',
|
||||
'--cov',
|
||||
'rest_framework'] + pytest_args
|
||||
|
||||
if first_arg.startswith('-'):
|
||||
# `runtests.py [flags]`
|
||||
|
|
|
@ -63,7 +63,7 @@ class RegularFieldsModel(models.Model):
|
|||
positive_small_integer_field = models.PositiveSmallIntegerField()
|
||||
slug_field = models.SlugField(max_length=100)
|
||||
small_integer_field = models.SmallIntegerField()
|
||||
text_field = models.TextField()
|
||||
text_field = models.TextField(max_length=100)
|
||||
time_field = models.TimeField()
|
||||
url_field = models.URLField(max_length=100)
|
||||
custom_field = CustomField()
|
||||
|
@ -161,11 +161,12 @@ class TestRegularFieldMappings(TestCase):
|
|||
positive_small_integer_field = IntegerField()
|
||||
slug_field = SlugField(max_length=100)
|
||||
small_integer_field = IntegerField()
|
||||
text_field = CharField(style={'base_template': 'textarea.html'})
|
||||
text_field = CharField(max_length=100, style={'base_template': 'textarea.html'})
|
||||
time_field = TimeField()
|
||||
url_field = URLField(max_length=100)
|
||||
custom_field = ModelField(model_field=<tests.test_model_serializer.CustomField: custom_field>)
|
||||
""")
|
||||
|
||||
self.assertEqual(unicode_repr(TestSerializer()), expected)
|
||||
|
||||
def test_field_options(self):
|
||||
|
|
12
tox.ini
12
tox.ini
|
@ -19,9 +19,9 @@ commands = ./runtests.py --fast {posargs} --coverage
|
|||
setenv =
|
||||
PYTHONDONTWRITEBYTECODE=1
|
||||
deps =
|
||||
django17: Django==1.7.10 # Should track maximum supported
|
||||
django18: Django==1.8.4 # Should track maximum supported
|
||||
django19: https://www.djangoproject.com/download/1.9a1/tarball/
|
||||
django17: Django==1.7.10
|
||||
django18: Django==1.8.4
|
||||
django19: https://www.djangoproject.com/download/1.9b1/tarball/
|
||||
-rrequirements/requirements-testing.txt
|
||||
-rrequirements/requirements-optionals.txt
|
||||
|
||||
|
@ -40,21 +40,21 @@ deps =
|
|||
# Specify explicitly to exclude Django Guardian against Django 1.9
|
||||
[testenv:py27-django19]
|
||||
deps =
|
||||
https://www.djangoproject.com/download/1.9a1/tarball/
|
||||
https://www.djangoproject.com/download/1.9b1/tarball/
|
||||
-rrequirements/requirements-testing.txt
|
||||
markdown==2.5.2
|
||||
django-filter==0.10.0
|
||||
|
||||
[testenv:py34-django19]
|
||||
deps =
|
||||
https://www.djangoproject.com/download/1.9a1/tarball/
|
||||
https://www.djangoproject.com/download/1.9b1/tarball/
|
||||
-rrequirements/requirements-testing.txt
|
||||
markdown==2.5.2
|
||||
django-filter==0.10.0
|
||||
|
||||
[testenv:py35-django19]
|
||||
deps =
|
||||
https://www.djangoproject.com/download/1.9a1/tarball/
|
||||
https://www.djangoproject.com/download/1.9b1/tarball/
|
||||
-rrequirements/requirements-testing.txt
|
||||
markdown==2.5.2
|
||||
django-filter==0.10.0
|
||||
|
|
Loading…
Reference in New Issue
Block a user