Esempio n. 1
0
 def test_site_name_default(self):
     site = Site(
         hostname="example.com",
         port=80,
         site_name="example dot com",
         is_default_site=True,
     )
     self.assertEqual(site.__str__(), "example dot com [default]")
Esempio n. 2
0
    def test_oops_there_is_more_than_one(self):
        Site.objects.create(
            hostname="example.com",
            is_default_site=True,
            root_page=Page.objects.get(pk=2),
        )

        site = Site(
            hostname="test.com", is_default_site=True, root_page=Page.objects.get(pk=2)
        )
        with self.assertRaises(Site.MultipleObjectsReturned):
            # If there already are multiple default sites, you're in trouble
            site.clean_fields()
Esempio n. 3
0
    def test_for_request_result_caching(self):
        # repeat test to show caching is unique per request instance,
        # even when the requests are for the same site
        for i, request in enumerate([self.get_request(), self.get_request()], 1):
            with self.subTest(attempt=i):

                # force site query beforehand
                Site.find_for_request(request)

                # only the first lookup should result in a query
                with self.assertNumQueries(1):
                    for i in range(4):
                        TestSiteSetting.for_request(request)
Esempio n. 4
0
    def test_models_cached(self):
        """Accessing a setting should only hit the DB once per render"""
        get_title = '{{ settings("tests.testgenericsetting").title }}'

        request = self.get_request()
        # run extra query before hand
        Site.find_for_request(request)

        for i in range(1, 4):
            with self.assertNumQueries(1):
                context = {"request": request}
                template = self.engine.from_string(get_title * i)
                self.assertEqual(template.render(context),
                                 self.default_settings.title * i)
Esempio n. 5
0
    def test_select_related(self, expected_queries=4):
        """The `select_related` attribute on setting models is `None` by default, so fetching foreign keys values requires additional queries"""
        request = self.get_request()

        self._create_importantpages_object()

        # force site query beforehand
        Site.find_for_request(request)

        # fetch settings and access foreiegn keys
        with self.assertNumQueries(expected_queries):
            settings = ImportantPages.for_request(request)
            settings.sign_up_page
            settings.general_terms_page
            settings.privacy_policy_page
Esempio n. 6
0
        def resolve_pages(self, info, **kwargs):
            pages = (WagtailPage.objects.live().public().filter(
                depth__gt=1).specific())  # no need to the root page

            if kwargs.get("in_site", False):
                site = Site.find_for_request(info.context)
                pages = pages.in_site(site)

            content_type = kwargs.pop("content_type", None)
            if content_type:
                app_label, model = content_type.strip().lower().split(".")
                try:
                    ctype = ContentType.objects.get(app_label=app_label,
                                                    model=model)
                except:  # noqa
                    return (WagtailPage.objects.none()
                            )  # something not quite right here, bail out early
                else:
                    pages = pages.filter(content_type=ctype)

            language_code = kwargs.pop("language_code", None)

            if language_code:
                pages = pages.filter(locale__language_code=language_code)

            return resolve_queryset(pages, info, **kwargs)
Esempio n. 7
0
def slugurl(context, slug):
    """
    Returns the URL for the page that has the given slug.

    First tries to find a page on the current site. If that fails or a request
    is not available in the context, then returns the URL for the first page
    that matches the slug on any site.
    """

    page = None
    try:
        site = Site.find_for_request(context["request"])
        current_site = site
    except KeyError:
        # No site object found - allow the fallback below to take place.
        pass
    else:
        if current_site is not None:
            page = Page.objects.in_site(current_site).filter(slug=slug).first()

    # If no page is found, fall back to searching the whole tree.
    if page is None:
        page = Page.objects.filter(slug=slug).first()

    if page:
        # call pageurl() instead of page.relative_url() here so we get the ``accepts_kwarg`` logic
        return pageurl(context, page)
Esempio n. 8
0
    def get_wagtail_site(self):
        from wagtail.models import Site

        site = Site.find_for_request(self.request)
        if site is None:
            return Site.objects.select_related("root_page").get(is_default_site=True)
        return site
Esempio n. 9
0
def redirect_to_relevant_instance(request, app_name, model_name):
    model = get_model_from_url_params(app_name, model_name)

    if issubclass(model, BaseSiteSetting):
        # Redirect the user to the edit page for the current site
        # (or the current request does not correspond to a site, the first site in the list)
        site_request = Site.find_for_request(request)
        site = site_request or Site.objects.first()
        if not site:
            messages.error(
                request,
                _("This setting could not be opened because there is no site defined."),
            )
            return redirect("wagtailadmin_home")
        return redirect(
            "wagtailsettings:edit",
            app_name,
            model_name,
            site.pk,
        )
    elif issubclass(model, BaseGenericSetting):
        return redirect(
            "wagtailsettings:edit",
            app_name,
            model_name,
            model.load(request_or_site=request).id,
        )
    else:
        raise NotImplementedError
Esempio n. 10
0
    def test_models_cached(self):
        """Accessing a setting should only hit the DB once per request instance,
        even if using that request to rendering multiple times"""
        request = self.get_request()
        get_title = "{{ settings.tests.testgenericsetting.title }}"

        # force site query beforehand
        Site.find_for_request(request)

        with self.assertNumQueries(1):
            for i in range(1, 4):
                with self.subTest(attempt=i):
                    self.assertEqual(
                        self.render(request, get_title * i),
                        self.default_settings.title * i,
                    )
Esempio n. 11
0
def pageurl(context, page, fallback=None):
    """
    Outputs a page's URL as relative (/foo/bar/) if it's within the same site as the
    current page, or absolute (http://example.com/foo/bar/) if not.
    If kwargs contains a fallback view name and page is None, the fallback view url will be returned.
    """
    if page is None and fallback:
        return resolve_url(fallback)

    if not hasattr(page, "relative_url"):
        raise ValueError("pageurl tag expected a Page object, got %r" % page)

    try:
        site = Site.find_for_request(context["request"])
        current_site = site
    except KeyError:
        # request not available in the current context; fall back on page.url
        return page.url

    if current_site is None:
        # request does not correspond to a recognised site; fall back on page.url
        return page.url

    # Pass page.relative_url the request object, which may contain a cached copy of
    # Site.get_site_root_paths()
    # This avoids page.relative_url having to make a database/cache fetch for this list
    # each time it's called.
    return page.relative_url(current_site, request=context.get("request"))
Esempio n. 12
0
 def test_get_base_url_prefers_setting(self):
     request = RequestFactory().get("/")
     site = self.prepare_site()
     self.assertEqual(site, Site.find_for_request(request))
     self.assertEqual(get_base_url(request), "https://bar.example.com")
     with override_settings(WAGTAILAPI_BASE_URL=None):
         self.assertEqual(get_base_url(request),
                          "http://other.example.com:8080")
Esempio n. 13
0
 def _inner(request):
     site = Site.find_for_request(request)
     if site is None:
         # find_for_request() can't determine the site,
         # so no settings can be idenfified
         return {}
     else:
         return SettingsProxy(request)
Esempio n. 14
0
    def test_get_urls_with_request_site_cache_with_i18n(self):
        request, django_site = self.get_request_and_django_site("/sitemap.xml")
        req_protocol = request.scheme

        sitemap = Sitemap(request)

        # pre-seed find_for_request cache, so that it's not counted towards the query count
        Site.find_for_request(request)

        with self.assertNumQueries(16):
            urls = [
                url["location"]
                for url in sitemap.get_urls(1, django_site, req_protocol)
            ]

        self.assertIn("http://localhost/", urls)  # Homepage
        self.assertIn("http://localhost/hello-world/", urls)  # Child page
Esempio n. 15
0
 def process_request(self, request):
     """
     Set request.site to contain the Site object responsible for handling this request,
     according to hostname matching rules
     """
     try:
         request.site = Site.find_for_request(request)
     except Site.DoesNotExist:
         request.site = None
Esempio n. 16
0
    def test_result_order_when_multiple_sites_share_the_same_root_page(self):
        result = Site.get_site_root_paths()

        # An entry for the default site should come first
        self.assertEqual(result[0][0], self.default_site.id)

        # Followed by entries for others in 'host' alphabetical order
        self.assertEqual(result[1][0], self.abc_site.id)
        self.assertEqual(result[2][0], self.def_site.id)
Esempio n. 17
0
def get_base_url(request=None):
    site = Site.find_for_request(request)
    base_url = getattr(settings, 'WAGTAILAPI_BASE_URL',
                       site.root_url if request and site else None)

    if base_url:
        # We only want the scheme and netloc
        base_url_parsed = urlparse(base_url)

        return base_url_parsed.scheme + '://' + base_url_parsed.netloc
Esempio n. 18
0
 def resolve_page(self, info, **kwargs):
     return preview_observable(
         id=kwargs.get("id"),
         slug=kwargs.get("slug"),
         url_path=kwargs.get("url_path"),
         token=kwargs.get("token"),
         content_type=kwargs.get("content_type"),
         site=Site.find_for_request(info.context) if kwargs.get(
             "in_site", False) else None,
     )
Esempio n. 19
0
def wagtail_site(context):
    """
    Returns the Site object for the given request
    """
    try:
        request = context["request"]
    except KeyError:
        return None

    return Site.find_for_request(request=request)
Esempio n. 20
0
        def resolve_page(self, info, **kwargs):

            return get_specific_page(
                id=kwargs.get("id"),
                slug=kwargs.get("slug"),
                url_path=kwargs.get("url_path"),
                language_code=kwargs.get("language_code"),
                token=kwargs.get("token"),
                content_type=kwargs.get("content_type"),
                site=Site.find_for_request(info.context) if kwargs.get(
                    "in_site", False) else None,
            )
Esempio n. 21
0
def edit_current_site(request, app_name, model_name):
    # Redirect the user to the edit page for the current site
    # (or the current request does not correspond to a site, the first site in the list)
    site_request = Site.find_for_request(request)
    site = site_request or Site.objects.first()
    if not site:
        messages.error(
            request,
            _("This setting could not be opened because there is no site defined."
              ),
        )
        return redirect("wagtailadmin_home")
    return redirect("wagtailsettings:edit", app_name, model_name, site.pk)
Esempio n. 22
0
def _get_redirect(request, path):
    if ("\0" in path
        ):  # reject URLs with null characters, which crash on Postgres (#4496)
        return None

    site = Site.find_for_request(request)
    try:
        return models.Redirect.get_for_site(site).get(old_path=path)
    except models.Redirect.MultipleObjectsReturned:
        # We have a site-specific and a site-ambivalent redirect; prefer the specific one
        return models.Redirect.objects.get(site=site, old_path=path)
    except models.Redirect.DoesNotExist:
        return None
Esempio n. 23
0
def get_base_url(request=None):
    base_url = getattr(settings, "WAGTAILAPI_BASE_URL", None)

    if base_url is None and request:
        site = Site.find_for_request(request)
        if site:
            base_url = site.root_url

    if base_url:
        # We only want the scheme and netloc
        base_url_parsed = urlparse(force_str(base_url))

        return base_url_parsed.scheme + "://" + base_url_parsed.netloc
Esempio n. 24
0
 def for_request(cls, request):
     """
     Get or create an instance of this model for the request,
     and cache the result on the request for faster repeat access.
     """
     attr_name = cls.get_cache_attr_name()
     if hasattr(request, attr_name):
         return getattr(request, attr_name)
     site = Site.find_for_request(request)
     site_settings = cls.for_site(site)
     # to allow more efficient page url generation
     site_settings._request = request
     setattr(request, attr_name, site_settings)
     return site_settings
Esempio n. 25
0
def get_setting(context, model_string, use_default_site=False):
    cache_key = None
    if use_default_site:
        cache_key = Site.objects.get(is_default_site=True)
    elif "request" in context:
        cache_key = Site.find_for_request(context["request"])

    # Sadly, WeakKeyDictionary can not implement __missing__, so we have to do
    # this one manually
    try:
        context_cache = settings_cache[context]
    except KeyError:
        context_cache = settings_cache[context] = SettingContextCache()
    # These ones all implement __missing__ in a useful way though
    return context_cache[cache_key][model_string]
Esempio n. 26
0
    def find_object(self, queryset, request):
        site = Site.find_for_request(request)
        if 'html_path' in request.GET and site is not None:
            path = request.GET['html_path']
            path_components = [component for component in path.split('/') if component]

            try:
                page, _, _ = site.root_page.specific.route(request, path_components)
            except Http404:
                return

            if queryset.filter(id=page.id).exists():
                return page

        return super().find_object(queryset, request)
Esempio n. 27
0
    def test_get_base_url_from_request(self):
        # base url for siteless request should be None
        request = RequestFactory().get("/")
        self.assertIsNone(Site.find_for_request(request))
        self.assertIsNone(get_base_url(request))

        # base url for request with a site should be based on the site's details
        site = self.prepare_site()
        self.clear_cached_site(request)
        self.assertEqual(site, Site.find_for_request(request))
        self.assertEqual(get_base_url(request),
                         "http://other.example.com:8080")

        # port 443 should indicate https without a port
        site.port = 443
        site.save()
        self.clear_cached_site(request)
        self.assertEqual(get_base_url(request), "https://other.example.com")

        # port 80 should indicate http without a port
        site.port = 80
        site.save()
        self.clear_cached_site(request)
        self.assertEqual(get_base_url(request), "http://other.example.com")
Esempio n. 28
0
def serve(request, path):
    # we need a valid Site object corresponding to this request in order to proceed
    site = Site.find_for_request(request)
    if not site:
        raise Http404

    path_components = [component for component in path.split("/") if component]
    page, args, kwargs = site.root_page.localized.specific.route(
        request, path_components
    )

    for fn in hooks.get_hooks("before_serve_page"):
        result = fn(page, request, args, kwargs)
        if isinstance(result, HttpResponse):
            return result

    return page.serve(request, *args, **kwargs)
Esempio n. 29
0
def get_setting(context, model_string, use_default_site=False):
    if use_default_site:
        site = Site.objects.get(is_default_site=True)
    elif "request" in context:
        site = Site.find_for_request(context["request"])
    else:
        raise RuntimeError("No request found in context, and use_default_site "
                           "flag not set")

    # Sadly, WeakKeyDictionary can not implement __missing__, so we have to do
    # this one manually
    try:
        context_cache = settings_cache[context]
    except KeyError:
        context_cache = settings_cache[context] = ContextCache()
    # These ones all implement __missing__ in a useful way though
    return context_cache[site][model_string]
Esempio n. 30
0
    def get_base_queryset(self):
        """
        Returns a queryset containing all pages that can be seen by this user.

        This is used as the base for get_queryset and is also used to find the
        parent pages when using the child_of and descendant_of filters as well.
        """
        # Get live pages that are not in a private section
        queryset = Page.objects.all().public().live()
        site = Site.find_for_request(self.request)

        # Filter by site
        if site:
            queryset = queryset.descendant_of(site.root_page, inclusive=True)
        else:
            # No sites configured
            queryset = queryset.none()

        return queryset