mirror of
https://github.com/SectorLabs/django-localized-fields.git
synced 2025-10-24 08:18:58 +03:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5bb16af6a4 | ||
|
|
a55986d28c | ||
|
|
bcd1f1cc1a | ||
|
|
463c415be2 | ||
|
|
fbc1eec754 | ||
|
|
911251ebaa |
@@ -3,7 +3,7 @@ jobs:
|
|||||||
test-python36:
|
test-python36:
|
||||||
docker:
|
docker:
|
||||||
- image: python:3.6-alpine
|
- image: python:3.6-alpine
|
||||||
- image: postgres:11.0
|
- image: postgres:12.0
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: 'localizedfields'
|
POSTGRES_DB: 'localizedfields'
|
||||||
POSTGRES_USER: 'localizedfields'
|
POSTGRES_USER: 'localizedfields'
|
||||||
@@ -20,17 +20,16 @@ jobs:
|
|||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Run tests
|
name: Run tests
|
||||||
command: tox -e 'py36-dj{20,21,22,30,31}'
|
command: tox -e 'py36-dj{20,21,22,30,31,32}'
|
||||||
environment:
|
environment:
|
||||||
DATABASE_URL: 'postgres://localizedfields:localizedfields@localhost:5432/localizedfields'
|
DATABASE_URL: 'postgres://localizedfields:localizedfields@localhost:5432/localizedfields'
|
||||||
|
|
||||||
- store_test_results:
|
- store_test_results:
|
||||||
path: reports
|
path: reports
|
||||||
|
|
||||||
test-python37:
|
test-python37:
|
||||||
docker:
|
docker:
|
||||||
- image: python:3.7-alpine
|
- image: python:3.7-alpine
|
||||||
- image: postgres:11.0
|
- image: postgres:12.0
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: 'localizedfields'
|
POSTGRES_DB: 'localizedfields'
|
||||||
POSTGRES_USER: 'localizedfields'
|
POSTGRES_USER: 'localizedfields'
|
||||||
@@ -47,17 +46,16 @@ jobs:
|
|||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Run tests
|
name: Run tests
|
||||||
command: tox -e 'py37-dj{20,21,22,30,31}'
|
command: tox -e 'py37-dj{20,21,22,30,31,32}'
|
||||||
environment:
|
environment:
|
||||||
DATABASE_URL: 'postgres://localizedfields:localizedfields@localhost:5432/localizedfields'
|
DATABASE_URL: 'postgres://localizedfields:localizedfields@localhost:5432/localizedfields'
|
||||||
|
|
||||||
- store_test_results:
|
- store_test_results:
|
||||||
path: reports
|
path: reports
|
||||||
|
|
||||||
test-python38:
|
test-python38:
|
||||||
docker:
|
docker:
|
||||||
- image: python:3.8-alpine
|
- image: python:3.8-alpine
|
||||||
- image: postgres:11.0
|
- image: postgres:12.0
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: 'localizedfields'
|
POSTGRES_DB: 'localizedfields'
|
||||||
POSTGRES_USER: 'localizedfields'
|
POSTGRES_USER: 'localizedfields'
|
||||||
@@ -74,7 +72,7 @@ jobs:
|
|||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Run tests
|
name: Run tests
|
||||||
command: tox -e 'py38-dj{20,21,22,30,31}'
|
command: tox -e 'py38-dj{20,21,22,30,31,32,40,41,42}'
|
||||||
environment:
|
environment:
|
||||||
DATABASE_URL: 'postgres://localizedfields:localizedfields@localhost:5432/localizedfields'
|
DATABASE_URL: 'postgres://localizedfields:localizedfields@localhost:5432/localizedfields'
|
||||||
|
|
||||||
@@ -84,7 +82,7 @@ jobs:
|
|||||||
test-python39:
|
test-python39:
|
||||||
docker:
|
docker:
|
||||||
- image: python:3.9-alpine
|
- image: python:3.9-alpine
|
||||||
- image: postgres:11.0
|
- image: postgres:12.0
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: 'localizedfields'
|
POSTGRES_DB: 'localizedfields'
|
||||||
POSTGRES_USER: 'localizedfields'
|
POSTGRES_USER: 'localizedfields'
|
||||||
@@ -101,7 +99,60 @@ jobs:
|
|||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Run tests
|
name: Run tests
|
||||||
command: tox -e 'py39-dj{21,22,30,31}'
|
command: tox -e 'py39-dj{30,31,32,40,41,42}'
|
||||||
|
environment:
|
||||||
|
DATABASE_URL: 'postgres://localizedfields:localizedfields@localhost:5432/localizedfields'
|
||||||
|
|
||||||
|
- store_test_results:
|
||||||
|
path: reports
|
||||||
|
|
||||||
|
test-python310:
|
||||||
|
docker:
|
||||||
|
- image: python:3.10-alpine
|
||||||
|
- image: postgres:12.0
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: 'localizedfields'
|
||||||
|
POSTGRES_USER: 'localizedfields'
|
||||||
|
POSTGRES_PASSWORD: 'localizedfields'
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
name: Install packages
|
||||||
|
command: apk add postgresql-libs gcc musl-dev postgresql-dev git
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Install Python packages
|
||||||
|
command: pip install --progress-bar off .[test]
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Run tests
|
||||||
|
command: tox -e 'py310-dj{32,40,41,42,50}'
|
||||||
|
environment:
|
||||||
|
DATABASE_URL: 'postgres://localizedfields:localizedfields@localhost:5432/localizedfields'
|
||||||
|
|
||||||
|
- store_test_results:
|
||||||
|
path: reports
|
||||||
|
test-python311:
|
||||||
|
docker:
|
||||||
|
- image: python:3.11-alpine
|
||||||
|
- image: postgres:12.0
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: 'localizedfields'
|
||||||
|
POSTGRES_USER: 'localizedfields'
|
||||||
|
POSTGRES_PASSWORD: 'localizedfields'
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
name: Install packages
|
||||||
|
command: apk add postgresql-libs gcc musl-dev postgresql-dev git
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Install Python packages
|
||||||
|
command: pip install --progress-bar off .[test]
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Run tests
|
||||||
|
command: tox -e 'py311-dj{42,50}'
|
||||||
environment:
|
environment:
|
||||||
DATABASE_URL: 'postgres://localizedfields:localizedfields@localhost:5432/localizedfields'
|
DATABASE_URL: 'postgres://localizedfields:localizedfields@localhost:5432/localizedfields'
|
||||||
|
|
||||||
@@ -110,7 +161,7 @@ jobs:
|
|||||||
|
|
||||||
analysis:
|
analysis:
|
||||||
docker:
|
docker:
|
||||||
- image: python:3.7-alpine
|
- image: python:3.8-alpine
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
@@ -134,4 +185,6 @@ workflows:
|
|||||||
- test-python37
|
- test-python37
|
||||||
- test-python38
|
- test-python38
|
||||||
- test-python39
|
- test-python39
|
||||||
|
- test-python310
|
||||||
|
- test-python311
|
||||||
- analysis
|
- analysis
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
| | | |
|
| | | |
|
||||||
|--------------------|---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|--------------------|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| :white_check_mark: | **Tests** | [](https://circleci.com/gh/SectorLabs/django-localized-fields/tree/master) |
|
| :white_check_mark: | **Tests** | [](https://circleci.com/gh/SectorLabs/django-localized-fields/tree/master) |
|
||||||
| :memo: | **License** | [](http://doge.mit-license.org) |
|
| :memo: | **License** | [](http://doge.mit-license.org) |
|
||||||
| :package: | **PyPi** | [](https://pypi.python.org/pypi/django-localized-fields) |
|
| :package: | **PyPi** | [](https://pypi.python.org/pypi/django-localized-fields) |
|
||||||
| <img src="https://cdn.iconscout.com/icon/free/png-256/django-1-282754.png" width="22px" height="22px" align="center" /> | **Django Versions** | 2.0, 2.1, 2.2, 3.0, 3.1, 3.2 |
|
| <img src="https://cdn.iconscout.com/icon/free/png-256/django-1-282754.png" width="22px" height="22px" align="center" /> | **Django Versions** | 2.0, 2.1, 2.2, 3.0, 3.1, 3.2, 4.0, 4.1, 4.2, 5.0 |
|
||||||
| <img src="http://www.iconarchive.com/download/i73027/cornmanthe3rd/plex/Other-python.ico" width="22px" height="22px" align="center" /> | **Python Versions** | 3.6, 3.7, 3.8, 3.9 |
|
| <img src="http://www.iconarchive.com/download/i73027/cornmanthe3rd/plex/Other-python.ico" width="22px" height="22px" align="center" /> | **Python Versions** | 3.6, 3.7, 3.8, 3.9, 3.10, 3.11 |
|
||||||
| :book: | **Documentation** | [Read The Docs](https://django-localized-fields.readthedocs.io) |
|
| :book: | **Documentation** | [Read The Docs](https://django-localized-fields.readthedocs.io) |
|
||||||
| :warning: | **Upgrade** | [Upgrade fom v5.x](https://django-localized-fields.readthedocs.io/en/latest/releases.html#v6-0)
|
| :warning: | **Upgrade** | [Upgrade fom v5.x](https://django-localized-fields.readthedocs.io/en/latest/releases.html#v6-0)
|
||||||
| :checkered_flag: | **Installation** | [Installation Guide](https://django-localized-fields.readthedocs.io/en/latest/installation.html) |
|
| :checkered_flag: | **Installation** | [Installation Guide](https://django-localized-fields.readthedocs.io/en/latest/installation.html) |
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
## Working with the code
|
## Working with the code
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
* PostgreSQL 10 or newer.
|
* PostgreSQL 12 or newer.
|
||||||
* Django 2.0 or newer.
|
* Django 2.0 or newer.
|
||||||
* Python 3.6 or newer.
|
* Python 3.6 or newer.
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import html
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from .field import LocalizedField
|
from .field import LocalizedField
|
||||||
@@ -7,6 +9,23 @@ class LocalizedBleachField(LocalizedField):
|
|||||||
"""Custom version of :see:BleachField that is actually a
|
"""Custom version of :see:BleachField that is actually a
|
||||||
:see:LocalizedField."""
|
:see:LocalizedField."""
|
||||||
|
|
||||||
|
DEFAULT_SHOULD_ESCAPE = True
|
||||||
|
|
||||||
|
def __init__(self, *args, escape=True, **kwargs):
|
||||||
|
"""Initializes a new instance of :see:LocalizedBleachField."""
|
||||||
|
|
||||||
|
self.escape = escape
|
||||||
|
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def deconstruct(self):
|
||||||
|
name, path, args, kwargs = super().deconstruct()
|
||||||
|
|
||||||
|
if self.escape != self.DEFAULT_SHOULD_ESCAPE:
|
||||||
|
kwargs["escape"] = self.escape
|
||||||
|
|
||||||
|
return name, path, args, kwargs
|
||||||
|
|
||||||
def pre_save(self, instance, add: bool):
|
def pre_save(self, instance, add: bool):
|
||||||
"""Ran just before the model is saved, allows us to built the slug.
|
"""Ran just before the model is saved, allows us to built the slug.
|
||||||
|
|
||||||
@@ -42,8 +61,14 @@ class LocalizedBleachField(LocalizedField):
|
|||||||
if not value:
|
if not value:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
cleaned_value = bleach.clean(
|
||||||
|
value if self.escape else html.unescape(value),
|
||||||
|
**get_bleach_default_options()
|
||||||
|
)
|
||||||
|
|
||||||
localized_value.set(
|
localized_value.set(
|
||||||
lang_code, bleach.clean(value, **get_bleach_default_options())
|
lang_code,
|
||||||
|
cleaned_value if self.escape else html.unescape(cleaned_value),
|
||||||
)
|
)
|
||||||
|
|
||||||
return localized_value
|
return localized_value
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ class LocalizedLookupMixin:
|
|||||||
return super().process_lhs(qn, connection)
|
return super().process_lhs(qn, connection)
|
||||||
|
|
||||||
def get_prep_lookup(self):
|
def get_prep_lookup(self):
|
||||||
|
# Django 4.0 removed the ability for isnull fields to be something other than a bool
|
||||||
|
# We should NOT convert them to strings
|
||||||
|
if isinstance(self.rhs, bool):
|
||||||
|
return self.rhs
|
||||||
return str(self.rhs)
|
return str(self.rhs)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
20
setup.py
20
setup.py
@@ -36,7 +36,7 @@ with open(
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="django-localized-fields",
|
name="django-localized-fields",
|
||||||
version="6.7",
|
version="6.8b4",
|
||||||
packages=find_packages(exclude=["tests"]),
|
packages=find_packages(exclude=["tests"]),
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
license="MIT License",
|
license="MIT License",
|
||||||
@@ -67,6 +67,8 @@ setup(
|
|||||||
"Programming Language :: Python :: 3.7",
|
"Programming Language :: Python :: 3.7",
|
||||||
"Programming Language :: Python :: 3.8",
|
"Programming Language :: Python :: 3.8",
|
||||||
"Programming Language :: Python :: 3.9",
|
"Programming Language :: Python :: 3.9",
|
||||||
|
"Programming Language :: Python :: 3.10",
|
||||||
|
"Programming Language :: Python :: 3.11",
|
||||||
"Topic :: Internet :: WWW/HTTP",
|
"Topic :: Internet :: WWW/HTTP",
|
||||||
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
|
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
|
||||||
],
|
],
|
||||||
@@ -74,20 +76,20 @@ setup(
|
|||||||
install_requires=[
|
install_requires=[
|
||||||
"Django>=2.0",
|
"Django>=2.0",
|
||||||
"django-postgres-extra>=2.0,<3.0",
|
"django-postgres-extra>=2.0,<3.0",
|
||||||
"deprecation==2.0.7",
|
"deprecation>=2.0.7",
|
||||||
],
|
],
|
||||||
extras_require={
|
extras_require={
|
||||||
':python_version <= "3.6"': ["dataclasses"],
|
':python_version <= "3.6"': ["dataclasses"],
|
||||||
"docs": ["Sphinx==2.2.0", "sphinx-rtd-theme==0.4.3"],
|
"docs": ["Sphinx==2.2.0", "sphinx-rtd-theme==0.4.3"],
|
||||||
"test": [
|
"test": [
|
||||||
"tox==3.14.3",
|
"tox==3.28.0",
|
||||||
"pytest==5.3.2",
|
"pytest==7.0.1",
|
||||||
"pytest-django==3.7.0",
|
"pytest-django==4.5.2",
|
||||||
"pytest-cov==2.8.1",
|
"pytest-cov==2.12.1",
|
||||||
"dj-database-url==0.5.0",
|
"dj-database-url==0.5.0",
|
||||||
"django-autoslug==1.9.6",
|
"django-autoslug==1.9.9",
|
||||||
"django-bleach==0.6.1",
|
"django-bleach==0.9.0",
|
||||||
"psycopg2==2.8.4",
|
"psycopg2==2.9.8",
|
||||||
],
|
],
|
||||||
"analysis": [
|
"analysis": [
|
||||||
"black==22.3.0",
|
"black==22.3.0",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"""isort:skip_file."""
|
"""isort:skip_file."""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import html
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -66,14 +67,24 @@ class LocalizedBleachFieldTestCase(TestCase):
|
|||||||
bleached_value = field.pre_save(model, False)
|
bleached_value = field.pre_save(model, False)
|
||||||
self._validate(value, bleached_value)
|
self._validate(value, bleached_value)
|
||||||
|
|
||||||
|
def test_pre_save_do_not_escape(self):
|
||||||
|
"""Tests whether the :see:pre_save function works properly when field
|
||||||
|
escape argument is set to False."""
|
||||||
|
|
||||||
|
value = self._get_test_value()
|
||||||
|
model, field = self._get_test_model(value, escape=False)
|
||||||
|
|
||||||
|
bleached_value = field.pre_save(model, False)
|
||||||
|
self._validate(value, bleached_value, False)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_test_model(value):
|
def _get_test_model(value, escape=True):
|
||||||
"""Gets a test model and a artifically constructed
|
"""Gets a test model and an artificially constructed
|
||||||
:see:LocalizedBleachField instance to test with."""
|
:see:LocalizedBleachField instance to test with."""
|
||||||
|
|
||||||
model = ModelTest(value)
|
model = ModelTest(value)
|
||||||
|
|
||||||
field = LocalizedBleachField()
|
field = LocalizedBleachField(escape=escape)
|
||||||
field.attname = "value"
|
field.attname = "value"
|
||||||
return model, field
|
return model, field
|
||||||
|
|
||||||
@@ -89,7 +100,7 @@ class LocalizedBleachFieldTestCase(TestCase):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _validate(non_bleached_value, bleached_value):
|
def _validate(non_bleached_value, bleached_value, escaped_value=True):
|
||||||
"""Validates whether the specified non-bleached value ended up being
|
"""Validates whether the specified non-bleached value ended up being
|
||||||
correctly bleached.
|
correctly bleached.
|
||||||
|
|
||||||
@@ -100,14 +111,20 @@ class LocalizedBleachFieldTestCase(TestCase):
|
|||||||
bleached_value:
|
bleached_value:
|
||||||
The value after bleaching.
|
The value after bleaching.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for lang_code, _ in settings.LANGUAGES:
|
for lang_code, _ in settings.LANGUAGES:
|
||||||
if not non_bleached_value.get(lang_code):
|
if not non_bleached_value.get(lang_code):
|
||||||
assert not bleached_value.get(lang_code)
|
assert not bleached_value.get(lang_code)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
expected_value = bleach.clean(
|
cleaned_value = bleach.clean(
|
||||||
non_bleached_value.get(lang_code), get_bleach_default_options()
|
non_bleached_value.get(lang_code)
|
||||||
|
if escaped_value
|
||||||
|
else html.unescape(non_bleached_value.get(lang_code)),
|
||||||
|
get_bleach_default_options(),
|
||||||
|
)
|
||||||
|
|
||||||
|
expected_value = (
|
||||||
|
cleaned_value if escaped_value else html.unescape(cleaned_value)
|
||||||
)
|
)
|
||||||
|
|
||||||
assert bleached_value.get(lang_code) == expected_value
|
assert bleached_value.get(lang_code) == expected_value
|
||||||
|
|||||||
51
tests/test_isnull.py
Normal file
51
tests/test_isnull.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import django
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from localized_fields.fields import LocalizedField
|
||||||
|
from localized_fields.value import LocalizedValue
|
||||||
|
|
||||||
|
from .fake_model import get_fake_model
|
||||||
|
|
||||||
|
|
||||||
|
class LocalizedIsNullLookupsTestCase(TestCase):
|
||||||
|
"""Tests whether ref lookups properly work with."""
|
||||||
|
|
||||||
|
TestModel1 = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
"""Creates the test model in the database."""
|
||||||
|
super(LocalizedIsNullLookupsTestCase, cls).setUpClass()
|
||||||
|
cls.TestModel = get_fake_model(
|
||||||
|
{"text": LocalizedField(null=True, required=[])}
|
||||||
|
)
|
||||||
|
cls.TestModel.objects.create(
|
||||||
|
text=LocalizedValue(dict(en="text_en", ro="text_ro", nl="text_nl"))
|
||||||
|
)
|
||||||
|
cls.TestModel.objects.create(
|
||||||
|
text=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_isnull_lookup_valid_values(self):
|
||||||
|
"""Test whether isnull properly works with valid values."""
|
||||||
|
assert self.TestModel.objects.filter(text__isnull=True).exists()
|
||||||
|
assert self.TestModel.objects.filter(text__isnull=False).exists()
|
||||||
|
|
||||||
|
def test_isnull_lookup_null(self):
|
||||||
|
"""Test whether isnull crashes with None as value."""
|
||||||
|
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
assert self.TestModel.objects.filter(text__isnull=None).exists()
|
||||||
|
|
||||||
|
def test_isnull_lookup_string(self):
|
||||||
|
"""Test whether isnull properly works with string values on the
|
||||||
|
corresponding Django version."""
|
||||||
|
if django.VERSION < (4, 0):
|
||||||
|
assert self.TestModel.objects.filter(text__isnull="True").exists()
|
||||||
|
else:
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
assert self.TestModel.objects.filter(
|
||||||
|
text__isnull="True"
|
||||||
|
).exists()
|
||||||
7
tox.ini
7
tox.ini
@@ -1,5 +1,5 @@
|
|||||||
[tox]
|
[tox]
|
||||||
envlist = py36-dj{20,21,22,30,31}, py37-dj{20,21,22,30,31}, py38-dj{20,21,22,30,31}, py39-dj{21,22,30,31}
|
envlist = py36-dj{20,21,22,30,31,32}, py37-dj{20,21,22,30,31,32}, py38-dj{20,21,22,30,31,32,40,41,42}, py39-dj{30,31,32,40,41,42}, py310-dj{32,40,41,42,50}, py311-dj{42,50}
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
deps =
|
deps =
|
||||||
@@ -8,6 +8,11 @@ deps =
|
|||||||
dj22: Django>=2.2,<2.3
|
dj22: Django>=2.2,<2.3
|
||||||
dj30: Django>=3.0,<3.0.2
|
dj30: Django>=3.0,<3.0.2
|
||||||
dj31: Django>=3.1,<3.2
|
dj31: Django>=3.1,<3.2
|
||||||
|
dj32: Django>=3.2,<4.0
|
||||||
|
dj40: Django>=4.0,<4.1
|
||||||
|
dj41: Django>=4.1,<4.2
|
||||||
|
dj42: Django>=4.2,<5.0
|
||||||
|
dj50: Django>=5.0,<5.1
|
||||||
.[test]
|
.[test]
|
||||||
setenv =
|
setenv =
|
||||||
DJANGO_SETTINGS_MODULE=settings
|
DJANGO_SETTINGS_MODULE=settings
|
||||||
|
|||||||
Reference in New Issue
Block a user