Skip to content

Commit

Permalink
Merge branch 'release/0.3.39' into main
Browse files Browse the repository at this point in the history
erikvw committed Jan 24, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents ab893d7 + 176044f commit 374798f
Showing 13 changed files with 72 additions and 20 deletions.
3 changes: 3 additions & 0 deletions edc_sites/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .site import sites as site_sites

__all__ = ["site_sites"]
3 changes: 3 additions & 0 deletions edc_sites/admin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
from .site_admin import SiteAdmin
from .site_fieldset_tuple import site_fieldset_tuple
from .site_model_admin_mixin import SiteModelAdminMixin

__all__ = ["SiteAdmin", "SiteModelAdminMixin", "site_fieldset_tuple"]
2 changes: 2 additions & 0 deletions edc_sites/admin/list_filters.py
Original file line number Diff line number Diff line change
@@ -3,6 +3,8 @@

from ..site import sites

__all__ = ["SiteListFilter"]


class SiteListFilter(SimpleListFilter):
title = "Site"
2 changes: 2 additions & 0 deletions edc_sites/admin/site_admin.py
Original file line number Diff line number Diff line change
@@ -4,6 +4,8 @@

from ..admin_site import edc_sites_admin

__all__ = ["SiteAdmin"]

admin.site.unregister(Site)


8 changes: 8 additions & 0 deletions edc_sites/admin/site_fieldset_tuple.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.utils.translation import gettext_lazy as _

__all__ = ["site_fieldset_tuple"]

site_fieldset_tuple: tuple[str, dict[str, tuple[str, ...]]] = (
_("Site"),
{"classes": ("collapse",), "fields": ["site"]},
)
9 changes: 9 additions & 0 deletions edc_sites/admin/site_model_admin_mixin.py
Original file line number Diff line number Diff line change
@@ -10,6 +10,8 @@
from ..site import sites
from .list_filters import SiteListFilter

__all__ = ["SiteModelAdminMixin"]


class SiteModeAdminMixinError(Exception):
pass
@@ -61,6 +63,13 @@ def get_list_display(self, request):
list_display = (list_display[0],) + (self.site_code,) + list_display[1:]
return list_display

def get_readonly_fields(self, request, obj=None) -> tuple[str, ...]:
"""Add site to readonly_fields."""
readonly_fields = super().get_readonly_fields(request, obj=obj)
if "site" not in readonly_fields:
return readonly_fields + ("site",)
return readonly_fields

def get_queryset(self, request) -> QuerySet:
"""Limit modeladmin queryset for the current site only"""
qs = super().get_queryset(request)
2 changes: 1 addition & 1 deletion edc_sites/model_mixins/site_model_mixin.py
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ class SiteModelMixin(models.Model):
"sites.site",
on_delete=models.PROTECT,
null=True,
editable=False,
# editable=False,
related_name="+",
)

13 changes: 13 additions & 0 deletions edc_sites/modelform_mixins.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
from __future__ import annotations

from typing import TYPE_CHECKING

from django import forms

if TYPE_CHECKING:
from django.contrib.sites.models import Site

__all__ = ["SiteModelFormMixin"]


class SiteModelFormMixin:

@@ -22,6 +31,10 @@ def clean(self) -> dict:
self.validate_with_current_site(cleaned_data)
return cleaned_data

@property
def site(self) -> Site:
return self.cleaned_data.get("site") or self.instance.site or self.related_visit.site

def validate_with_current_site(self, cleaned_data: dict) -> None:
current_site = getattr(self, "current_site", None)
if (
4 changes: 2 additions & 2 deletions edc_sites/single_site/single_site.py
Original file line number Diff line number Diff line change
@@ -13,9 +13,9 @@ class SiteCountryRequiredError(Exception):
pass


@dataclass(init=True)
@dataclass(order=True)
class SingleSite:
site_id: int
site_id: int = field(compare=True)
name: str
domain: str
_: KW_ONLY
29 changes: 17 additions & 12 deletions edc_sites/site.py
Original file line number Diff line number Diff line change
@@ -9,7 +9,6 @@
from django.apps import apps as django_apps
from django.conf import settings
from django.contrib import messages
from django.contrib.sites.shortcuts import get_current_site
from django.core.exceptions import ObjectDoesNotExist
from django.core.handlers.wsgi import WSGIRequest as BaseWSGIRequest
from django.core.management.color import color_style
@@ -18,7 +17,7 @@
from edc_model_admin.utils import add_to_messages_once

from .auths import view_auditallsites_codename
from .exceptions import InvalidSiteError, InvalidSiteForUser
from .exceptions import InvalidSiteForUser
from .single_site import SingleSite
from .utils import (
get_change_codenames,
@@ -239,13 +238,6 @@ def get_view_only_site_ids_for_user(
if request:
user = request.user
site_id = request.site.id

if site_id != get_current_site(request).id:
raise InvalidSiteError(
f"Expected the current site. Current site is "
f"`{get_current_site(request).id}`. "
f"See user `{user}`. Got {site_id}."
)
site_id = sites.get(site_id).site_id
has_profile_or_raise(user)
sites.site_in_profile_or_raise(user=user, site_id=site_id)
@@ -265,8 +257,20 @@ def get_view_only_site_ids_for_user(
)
return site_ids

def user_may_view_other_sites(self, request: WSGIRequest) -> bool:
return True if self.get_view_only_site_ids_for_user(request=request) else False
def user_may_view_other_sites(
self,
request: WSGIRequest = None,
user: User = None,
site_id: int = None,
current_site_id: int = None,
) -> bool:
if self.get_view_only_site_ids_for_user(
request=request,
user=user,
site_id=site_id,
):
return True
return False

@staticmethod
def site_in_profile_or_raise(user: User, site_id: int) -> None:
@@ -295,7 +299,7 @@ def get_language_choices_tuple(
return tuple((k, v) for k, v in languages.items())

@staticmethod
def get_current_site_obj(request: WSGIRequest | None) -> Site:
def get_current_site_obj(request: WSGIRequest | None = None) -> Site:
if request:
return request.site
return get_site_model_cls().objects.get_current()
@@ -371,6 +375,7 @@ def autodiscover(self, module_name=None, verbose=True):
raise SitesError(str(e))
except ImportError:
pass
writer(f" Done loading {module_name}.\n")


sites = Sites()
3 changes: 1 addition & 2 deletions edc_sites/utils/get_message_text.py
Original file line number Diff line number Diff line change
@@ -5,8 +5,7 @@
def get_message_text(level: int) -> str:
if level == messages.WARNING:
return _(
"You have permissions to view data from multiple sites. "
"Pages may include data from sites other than the current site."
"You have permissions to view forms and data from sites other than the current. "
)
elif level == messages.ERROR:
return _(
7 changes: 5 additions & 2 deletions edc_sites/utils/valid_site_for_subject_or_raise.py
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@

if TYPE_CHECKING:
from django.contrib.sites.models import Site
from edc_registration.models import RegisteredSubject


def valid_site_for_subject_or_raise(
@@ -22,12 +23,14 @@ def valid_site_for_subject_or_raise(
* Confirms by querying RegisteredSubject.
* If subject_identifier is invalid will raise ObjectDoesNotExist
"""
registered_subject = get_registered_subject(subject_identifier, raise_exception=True)
registered_subject: RegisteredSubject | None = get_registered_subject(
subject_identifier, raise_exception=True
)
if skip_get_current_site:
warn("Skipping validation of current site against registered subject site.")
current_site = registered_subject.site
else:
current_site = get_site_model_cls().objects.get_current()
current_site: Site = get_site_model_cls().objects.get_current()
try:
registered_subject = get_registered_subject(
subject_identifier,
7 changes: 6 additions & 1 deletion runtests.py
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@
SITE_ID=10,
EDC_SITES_MODULE_NAME="edc_sites.tests.sites",
EDC_NAVBAR_VERIFY_ON_LOAD=IGNORE,
SUBJECT_VISIT_MODEL="edc_visit_tracking.subjectvisit",
INSTALLED_APPS=[
"django.contrib.admin",
"django.contrib.auth",
@@ -30,13 +31,17 @@
"django.contrib.sites",
"django_crypto_fields",
"edc_auth.apps.AppConfig",
"edc_action_item.apps.AppConfig",
"edc_appointment.apps.AppConfig",
"edc_dashboard.apps.AppConfig",
"edc_lab.apps.AppConfig",
"edc_listboard.apps.AppConfig",
"edc_navbar.apps.AppConfig",
"edc_notification.apps.AppConfig",
"edc_review_dashboard.apps.AppConfig",
"edc_subject_dashboard.apps.AppConfig",
"edc_visit_schedule.apps.AppConfig",
"edc_notification.apps.AppConfig",
"edc_visit_tracking.apps.AppConfig",
"multisite",
"edc_sites",
],

0 comments on commit 374798f

Please sign in to comment.