Skip to content

Commit

Permalink
Merge branch 'lazybird:master' into add-id-translations
Browse files Browse the repository at this point in the history
  • Loading branch information
kiraware authored Aug 6, 2024
2 parents b613339 + e516666 commit c3d5b3b
Show file tree
Hide file tree
Showing 21 changed files with 313 additions and 229 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ "3.7", "3.8", "3.9", "3.10", "3.11" ]
python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12" ]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ __pycache__
venv
dist
files
.mypy_cache

.DS_STORE
23 changes: 23 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
Unreleased
==========

django-solo-2.3.0
=================

Date: 1 July, 2024

* Add typing support
* Deprecate `solo.models.get_cache`
* Switch to `pyproject.toml`
* Switch to Ruff for formatting and linting

django-solo-2.2.0
=================

Date: 1 January, 2024

* Add support for Python 3.12
* Drop support for Python 3.7
* Add support for Django 5.0
* Drop support for end of life Django 4.0 and 4.1

django-solo-2.1.0
=================

Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
include *.md
include LICENSE
include CHANGES
include solo/py.typed
recursive-include solo/templates *
recursive-include solo/locale *.mo *.po
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,11 @@ To run the unit tests:

1. Update [`solo/__init__.py`](solo/__init__.py) `version`

2. Make a new release on GitHub
2. Update [`CHANGES`](./CHANGES)

3. Make a new release on GitHub

4. Upload release to PyPI

```shell
tox -e build
Expand Down
4 changes: 1 addition & 3 deletions examples/config/admin.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from django.contrib import admin

from solo.admin import SingletonModelAdmin

from config.models import SiteConfiguration

from solo.admin import SingletonModelAdmin

admin.site.register(SiteConfiguration, SingletonModelAdmin)
4 changes: 2 additions & 2 deletions examples/config/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@


class SiteConfiguration(SingletonModel):
site_name = models.CharField(max_length=255, default='Site Name')
site_name = models.CharField(max_length=255, default="Site Name")
maintenance_mode = models.BooleanField(default=False)

def __str__(self):
return u"Site Configuration"
return "Site Configuration"

class Meta:
verbose_name = "Site Configuration"
Expand Down
5 changes: 3 additions & 2 deletions manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
Note: For django-solo, this file is used simply to launch the test suite.
"""

import os
import sys


def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'test_project.settings')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_project.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
Expand All @@ -21,5 +22,5 @@ def main():
execute_from_command_line(sys.argv)


if __name__ == '__main__':
if __name__ == "__main__":
main()
69 changes: 69 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
[build-system]
requires = ["setuptools>=61.0.0"]
build-backend = "setuptools.build_meta"

[project]
name = "django-solo"
description = "Django Solo helps working with singletons"
authors = [{name = "lazybird"}]
maintainers = [
{name = "John Hagen", email = "johnthagen@gmail.com"}
]
readme = "README.md"
requires-python = ">=3.8"
classifiers = [
"Framework :: Django :: 3.2",
"Framework :: Django :: 4.2",
"Framework :: Django :: 5.0",
"Intended Audience :: Developers",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
]
dependencies = [
"django>=3.2",
"typing-extensions>=4.0.1; python_version < '3.11'",
]
license = {text = "Creative Commons Attribution 3.0 Unported"}
dynamic = ["version"]

[tool.setuptools.dynamic]
version = {attr = "solo.__version__"}

[project.urls]
Homepage = "https://github.com/lazybird/django-solo/"
Source = "https://github.com/lazybird/django-solo/"
Changelog = "https://github.com/lazybird/django-solo/blob/master/CHANGES"

[tool.mypy]
ignore_missing_imports = true
strict = true
exclude = "solo/tests"

[tool.ruff]
line-length = 100
target-version = "py38"

[tool.ruff.lint]
select = [
"F", # pyflakes
"E", # pycodestyle
"I", # isort
"N", # pep8-naming
"UP", # pyupgrade
"RUF", # ruff
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"PTH", # flake8-use-pathlib
"SIM", # flake8-simplify
"TID", # flake8-tidy-imports
]

ignore = [
"B904",
]
56 changes: 0 additions & 56 deletions setup.py

This file was deleted.

10 changes: 6 additions & 4 deletions solo/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
"""django-solo helps working with singletons: things like global settings that you want to edit from the admin site.
"""
import django
django-solo helps working with singletons:
things like global settings that you want to edit from the admin site.
"""

import django

__version__ = '2.1.0'
__version__ = "2.3.0"

if django.VERSION < (3, 2):
default_app_config = 'solo.apps.SoloAppConfig'
default_app_config = "solo.apps.SoloAppConfig"
84 changes: 48 additions & 36 deletions solo/admin.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
from django.urls import re_path
from __future__ import annotations

from typing import Any

from django.contrib import admin
from django.http import HttpResponseRedirect
from django.db.models import Model
from django.http import HttpRequest, HttpResponse, HttpResponseRedirect
from django.urls import URLPattern, re_path
from django.utils.encoding import force_str
from django.utils.translation import gettext as _

from solo.models import DEFAULT_SINGLETON_INSTANCE_ID
from solo import settings as solo_settings
from solo.models import DEFAULT_SINGLETON_INSTANCE_ID


class SingletonModelAdmin(admin.ModelAdmin):
class SingletonModelAdmin(admin.ModelAdmin): # type: ignore[type-arg]
object_history_template = "admin/solo/object_history.html"
change_form_template = "admin/solo/change_form.html"

def has_add_permission(self, request):
def has_add_permission(self, request: HttpRequest) -> bool:
return False

def has_delete_permission(self, request, obj=None):
def has_delete_permission(self, request: HttpRequest, obj: Model | None = None) -> bool:
return False

def get_urls(self):
urls = super(SingletonModelAdmin, self).get_urls()
def get_urls(self) -> list[URLPattern]:
urls = super().get_urls()

if not solo_settings.SOLO_ADMIN_SKIP_OBJECT_LIST_PAGE:
return urls
Expand All @@ -32,61 +37,68 @@ def get_urls(self):
model_name = self.model._meta.module_name.lower()

self.model._meta.verbose_name_plural = self.model._meta.verbose_name
url_name_prefix = '%(app_name)s_%(model_name)s' % {
'app_name': self.model._meta.app_label,
'model_name': model_name,
}
url_name_prefix = f"{self.model._meta.app_label}_{model_name}"
custom_urls = [
re_path(r'^history/$',
self.admin_site.admin_view(self.history_view),
{'object_id': str(self.singleton_instance_id)},
name='%s_history' % url_name_prefix),
re_path(r'^$',
self.admin_site.admin_view(self.change_view),
{'object_id': str(self.singleton_instance_id)},
name='%s_change' % url_name_prefix),
re_path(
r"^history/$",
self.admin_site.admin_view(self.history_view),
{"object_id": str(self.singleton_instance_id)},
name=f"{url_name_prefix}_history",
),
re_path(
r"^$",
self.admin_site.admin_view(self.change_view),
{"object_id": str(self.singleton_instance_id)},
name=f"{url_name_prefix}_change",
),
]

# By inserting the custom URLs first, we overwrite the standard URLs.
return custom_urls + urls

def response_change(self, request, obj):
msg = _('%(obj)s was changed successfully.') % {
'obj': force_str(obj)}
if '_continue' in request.POST:
self.message_user(request, msg + ' ' +
_('You may edit it again below.'))
def response_change(self, request: HttpRequest, obj: Model) -> HttpResponseRedirect:
msg = _("{obj} was changed successfully.").format(obj=force_str(obj))
if "_continue" in request.POST:
self.message_user(request, msg + " " + _("You may edit it again below."))
return HttpResponseRedirect(request.path)
else:
self.message_user(request, msg)
return HttpResponseRedirect("../../")

def change_view(self, request, object_id, form_url='', extra_context=None):
def change_view(
self,
request: HttpRequest,
object_id: str,
form_url: str = "",
extra_context: dict[str, Any] | None = None,
) -> HttpResponse:
if object_id == str(self.singleton_instance_id):
self.model.objects.get_or_create(pk=self.singleton_instance_id)

if not extra_context:
extra_context = dict()
extra_context['skip_object_list_page'] = solo_settings.SOLO_ADMIN_SKIP_OBJECT_LIST_PAGE
extra_context = {}
extra_context["skip_object_list_page"] = solo_settings.SOLO_ADMIN_SKIP_OBJECT_LIST_PAGE

return super(SingletonModelAdmin, self).change_view(
return super().change_view(
request,
object_id,
form_url=form_url,
extra_context=extra_context,
)

def history_view(self, request, object_id, extra_context=None):
def history_view(
self, request: HttpRequest, object_id: str, extra_context: dict[str, Any] | None = None
) -> HttpResponse:
if not extra_context:
extra_context = dict()
extra_context['skip_object_list_page'] = solo_settings.SOLO_ADMIN_SKIP_OBJECT_LIST_PAGE
extra_context = {}
extra_context["skip_object_list_page"] = solo_settings.SOLO_ADMIN_SKIP_OBJECT_LIST_PAGE

return super(SingletonModelAdmin, self).history_view(
return super().history_view(
request,
object_id,
extra_context=extra_context,
)

@property
def singleton_instance_id(self):
return getattr(self.model, 'singleton_instance_id', DEFAULT_SINGLETON_INSTANCE_ID)
def singleton_instance_id(self) -> int:
return getattr(self.model, "singleton_instance_id", DEFAULT_SINGLETON_INSTANCE_ID)
Loading

0 comments on commit c3d5b3b

Please sign in to comment.