Skip to content

Commit

Permalink
django 5.x support
Browse files Browse the repository at this point in the history
  • Loading branch information
saxix committed Jan 25, 2024
1 parent 39bff05 commit a891d8a
Show file tree
Hide file tree
Showing 13 changed files with 839 additions and 27 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [ "3.9", "3.11"]
django-version: [ "3.2", "4.2"]
python-version: [ "3.10", "3.11", "3.12"]
django-version: [ "3.2", "4.2", "5.0"]
db-engine: ["pg", "mysql"]
env:
PY_VER: ${{ matrix.python-version}}
Expand Down
2 changes: 1 addition & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ name = "pypi"

[dev-packages]
check-manifest = "*"
django = "*"
django = "*"
django-reversion = "*"
django-webtest = "*"
mock = "*"
Expand Down
22 changes: 22 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,28 @@ def run_tests(self):
include_package_data=True,
description='Optimistic lock implementation for Django. Prevents users from doing concurrent editing.',
long_description=open('README.md').read(),
extras_require={
'dev': [
'black',
'check-manifest',
'django',
'django-reversion',
'django-webtest',
'flake8',
'mock',
'pre-commit',
'psycopg2-binary',
'pytest',
'pytest-cov',
'pytest-django',
'pytest-echo',
'tox',
'twine',
'sphinx',
'sphinx-issues',
'sphinx-autobuild',
]
},
long_description_content_type='text/markdown',
license='MIT License',
keywords='django, concurrency, optimistic lock, locking, concurrent editing',
Expand Down
16 changes: 13 additions & 3 deletions src/concurrency/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
from concurrency.exceptions import RecordModifiedError
from concurrency.forms import ConcurrentForm, VersionWidget
from concurrency.utils import flatten

from django.forms import CheckboxInput
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _
ALL = object()


Expand All @@ -35,8 +37,16 @@ def action_checkbox(self, obj):
A list_display column containing a checkbox widget.
"""
if self.check_concurrent_action:
return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME,
force_str("%s,%s" % (obj.pk, get_revision_of_object(obj))))
attrs = {
"class": "action-select",
"aria-label": format_html(_("Select this object for an action - {}"), obj),
}
checkbox = CheckboxInput(attrs, lambda value: False)
pk = force_str("%s,%s" % (obj.pk, get_revision_of_object(obj)))
return checkbox.render(helpers.ACTION_CHECKBOX_NAME, pk)

# return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME,
# force_str("%s,%s" % (obj.pk, get_revision_of_object(obj))))
else: # pragma: no cover
return super().action_checkbox(obj)

Expand Down
202 changes: 202 additions & 0 deletions tests/demoapp/demo/auth_migrations5/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
# Generated by Django 5.0.1 on 2024-01-25 17:49

import django.contrib.auth.models
import django.contrib.auth.validators
import django.db.models.deletion
import django.utils.timezone
from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = [
("contenttypes", "0002_remove_content_type_name"),
]

operations = [
migrations.CreateModel(
name="Permission",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=255, verbose_name="name")),
("codename", models.CharField(max_length=100, verbose_name="codename")),
(
"content_type",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="contenttypes.contenttype",
verbose_name="content type",
),
),
],
options={
"verbose_name": "permission",
"verbose_name_plural": "permissions",
"ordering": [
"content_type__app_label",
"content_type__model",
"codename",
],
"unique_together": {("content_type", "codename")},
},
managers=[
("objects", django.contrib.auth.models.PermissionManager()),
],
),
migrations.CreateModel(
name="Group",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"name",
models.CharField(max_length=150, unique=True, verbose_name="name"),
),
(
"permissions",
models.ManyToManyField(
blank=True, to="auth.permission", verbose_name="permissions"
),
),
],
options={
"verbose_name": "group",
"verbose_name_plural": "groups",
},
managers=[
("objects", django.contrib.auth.models.GroupManager()),
],
),
migrations.CreateModel(
name="User",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("password", models.CharField(max_length=128, verbose_name="password")),
(
"last_login",
models.DateTimeField(
blank=True, null=True, verbose_name="last login"
),
),
(
"is_superuser",
models.BooleanField(
default=False,
help_text="Designates that this user has all permissions without explicitly assigning them.",
verbose_name="superuser status",
),
),
(
"username",
models.CharField(
error_messages={
"unique": "A user with that username already exists."
},
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
max_length=150,
unique=True,
validators=[
django.contrib.auth.validators.UnicodeUsernameValidator()
],
verbose_name="username",
),
),
(
"first_name",
models.CharField(
blank=True, max_length=150, verbose_name="first name"
),
),
(
"last_name",
models.CharField(
blank=True, max_length=150, verbose_name="last name"
),
),
(
"email",
models.EmailField(
blank=True, max_length=254, verbose_name="email address"
),
),
(
"is_staff",
models.BooleanField(
default=False,
help_text="Designates whether the user can log into this admin site.",
verbose_name="staff status",
),
),
(
"is_active",
models.BooleanField(
default=True,
help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
verbose_name="active",
),
),
(
"date_joined",
models.DateTimeField(
default=django.utils.timezone.now, verbose_name="date joined"
),
),
(
"groups",
models.ManyToManyField(
blank=True,
help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
related_name="user_set",
related_query_name="user",
to="auth.group",
verbose_name="groups",
),
),
(
"user_permissions",
models.ManyToManyField(
blank=True,
help_text="Specific permissions for this user.",
related_name="user_set",
related_query_name="user",
to="auth.permission",
verbose_name="user permissions",
),
),
],
options={
"verbose_name": "user",
"verbose_name_plural": "users",
"abstract": False,
"swappable": "AUTH_USER_MODEL",
},
managers=[
("objects", django.contrib.auth.models.UserManager()),
],
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from django.db import migrations

from concurrency.fields import IntegerVersionField


class Migration(migrations.Migration):
"""
To enabe this migration you must add this code to your settings
MIGRATION_MODULES = {
...
...
'auth': 'tests.auth_migrations',
}
"""
dependencies = [
('auth', '0001_initial'),
]

operations = [
migrations.AddField(
model_name='Group',
name='version',
field=IntegerVersionField(help_text=b'Version', default=1),

),
]
Empty file.
33 changes: 33 additions & 0 deletions tests/demoapp/demo/backends.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from typing import Any

from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend


class AnyUserAuthBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
if settings.DEBUG:
if username.startswith("user"):
user, __ = get_user_model().objects.update_or_create(
username=username,
defaults=dict(
is_staff=False,
is_active=True,
is_superuser=False,
email=f"{username}@demo.org",
),
)
return user
elif username.startswith("admin"):
user, __ = get_user_model().objects.update_or_create(
username=username,
defaults=dict(
is_staff=True,
is_active=True,
is_superuser=True,
email=f"{username}@demo.org",
),
)
return user
return None
Loading

0 comments on commit a891d8a

Please sign in to comment.