Skip to content

Commit

Permalink
Pr1312 (#1339)
Browse files Browse the repository at this point in the history
* Force evaluation of reverse_lazy urls in set_query_parameters. Fixes #1311

Passing reverse_lazy url to SpectacularRedocView errors because set_query_parameters calls urlls.parse.urlparse on url which may not be a string but a 'django.utils.functional.lazy.<locals>.__proxy__'. Forcing url to be string fixes this issue.

* Update plumbing.py

* fix second lazy url issue & add test #1312

---------

Co-authored-by: Işık Kaplan <[email protected]>
  • Loading branch information
tfranzel and isik-kaplan authored Nov 30, 2024
1 parent caf707d commit 10aa34a
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 2 deletions.
2 changes: 2 additions & 0 deletions drf_spectacular/plumbing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1283,6 +1283,7 @@ def build_mock_request(method, path, view, original_request, **kwargs):

def set_query_parameters(url, **kwargs) -> str:
""" deconstruct url, safely attach query parameters in kwargs, and serialize again """
url = str(url) # Force evaluation of reverse_lazy urls
scheme, netloc, path, params, query, fragment = urllib.parse.urlparse(url)
query = urllib.parse.parse_qs(query)
query.update({k: v for k, v in kwargs.items() if v is not None})
Expand All @@ -1291,6 +1292,7 @@ def set_query_parameters(url, **kwargs) -> str:


def get_relative_url(url: str) -> str:
url = str(url) # Force evaluation of reverse_lazy urls
scheme, netloc, path, params, query, fragment = urllib.parse.urlparse(url)
return urllib.parse.urlunparse(('', '', path, params, query, fragment))

Expand Down
15 changes: 13 additions & 2 deletions tests/test_plumbing.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@
from django.conf.urls import include
from django.db import models
from django.urls import re_path
from django.utils.functional import lazystr
from rest_framework import generics, serializers

from drf_spectacular.openapi import AutoSchema
from drf_spectacular.plumbing import (
analyze_named_regex_pattern, build_basic_type, build_choice_field, detype_pattern,
follow_field_source, force_instance, get_list_serializer, is_field, is_serializer,
resolve_type_hint, safe_ref,
follow_field_source, force_instance, get_list_serializer, get_relative_url, is_field,
is_serializer, resolve_type_hint, safe_ref, set_query_parameters,
)
from drf_spectacular.validation import validate_schema
from tests import generate_schema
Expand Down Expand Up @@ -437,3 +438,13 @@ def test_safe_ref():
schema = safe_ref(schema)
assert schema == {'$ref': '#/components/schemas/Foo'}
assert safe_ref(schema) == safe_ref(schema)


def test_url_tooling_with_lazy_url():
some_url = "http://api.example.org/accounts/"

assert get_relative_url(some_url) == "/accounts/"
assert set_query_parameters(some_url, foo=123) == some_url + "?foo=123"

assert get_relative_url(lazystr(some_url)) == "/accounts/"
assert set_query_parameters(lazystr(some_url), foo=123) == some_url + "?foo=123"

0 comments on commit 10aa34a

Please sign in to comment.