Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/django/shortcuts.py: 28%

47 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1""" 

2This module collects helper functions and classes that "span" multiple levels 

3of MVC. In other words, these functions/classes introduce controlled coupling 

4for convenience's sake. 

5""" 

6from django.http import ( 

7 Http404, 

8 HttpResponse, 

9 HttpResponsePermanentRedirect, 

10 HttpResponseRedirect, 

11) 

12from django.template import loader 

13from django.urls import NoReverseMatch, reverse 

14from django.utils.functional import Promise 

15 

16 

17def render( 

18 request, template_name, context=None, content_type=None, status=None, using=None 

19): 

20 """ 

21 Return an HttpResponse whose content is filled with the result of calling 

22 django.template.loader.render_to_string() with the passed arguments. 

23 """ 

24 content = loader.render_to_string(template_name, context, request, using=using) 

25 return HttpResponse(content, content_type, status) 

26 

27 

28def redirect(to, *args, permanent=False, **kwargs): 

29 """ 

30 Return an HttpResponseRedirect to the appropriate URL for the arguments 

31 passed. 

32 

33 The arguments could be: 

34 

35 * A model: the model's `get_absolute_url()` function will be called. 

36 

37 * A view name, possibly with arguments: `urls.reverse()` will be used 

38 to reverse-resolve the name. 

39 

40 * A URL, which will be used as-is for the redirect location. 

41 

42 Issues a temporary redirect by default; pass permanent=True to issue a 

43 permanent redirect. 

44 """ 

45 redirect_class = ( 

46 HttpResponsePermanentRedirect if permanent else HttpResponseRedirect 

47 ) 

48 return redirect_class(resolve_url(to, *args, **kwargs)) 

49 

50 

51def _get_queryset(klass): 

52 """ 

53 Return a QuerySet or a Manager. 

54 Duck typing in action: any class with a `get()` method (for 

55 get_object_or_404) or a `filter()` method (for get_list_or_404) might do 

56 the job. 

57 """ 

58 # If it is a model class or anything else with ._default_manager 

59 if hasattr(klass, "_default_manager"): 59 ↛ 60line 59 didn't jump to line 60, because the condition on line 59 was never true

60 return klass._default_manager.all() 

61 return klass 

62 

63 

64def get_object_or_404(klass, *args, **kwargs): 

65 """ 

66 Use get() to return an object, or raise an Http404 exception if the object 

67 does not exist. 

68 

69 klass may be a Model, Manager, or QuerySet object. All other passed 

70 arguments and keyword arguments are used in the get() query. 

71 

72 Like with QuerySet.get(), MultipleObjectsReturned is raised if more than 

73 one object is found. 

74 """ 

75 queryset = _get_queryset(klass) 

76 if not hasattr(queryset, "get"): 76 ↛ 77line 76 didn't jump to line 77

77 klass__name = ( 

78 klass.__name__ if isinstance(klass, type) else klass.__class__.__name__ 

79 ) 

80 raise ValueError( 

81 "First argument to get_object_or_404() must be a Model, Manager, " 

82 "or QuerySet, not '%s'." % klass__name 

83 ) 

84 try: 

85 return queryset.get(*args, **kwargs) 

86 except queryset.model.DoesNotExist: 

87 raise Http404( 

88 "No %s matches the given query." % queryset.model._meta.object_name 

89 ) 

90 

91 

92def get_list_or_404(klass, *args, **kwargs): 

93 """ 

94 Use filter() to return a list of objects, or raise an Http404 exception if 

95 the list is empty. 

96 

97 klass may be a Model, Manager, or QuerySet object. All other passed 

98 arguments and keyword arguments are used in the filter() query. 

99 """ 

100 queryset = _get_queryset(klass) 

101 if not hasattr(queryset, "filter"): 

102 klass__name = ( 

103 klass.__name__ if isinstance(klass, type) else klass.__class__.__name__ 

104 ) 

105 raise ValueError( 

106 "First argument to get_list_or_404() must be a Model, Manager, or " 

107 "QuerySet, not '%s'." % klass__name 

108 ) 

109 obj_list = list(queryset.filter(*args, **kwargs)) 

110 if not obj_list: 

111 raise Http404( 

112 "No %s matches the given query." % queryset.model._meta.object_name 

113 ) 

114 return obj_list 

115 

116 

117def resolve_url(to, *args, **kwargs): 

118 """ 

119 Return a URL appropriate for the arguments passed. 

120 

121 The arguments could be: 

122 

123 * A model: the model's `get_absolute_url()` function will be called. 

124 

125 * A view name, possibly with arguments: `urls.reverse()` will be used 

126 to reverse-resolve the name. 

127 

128 * A URL, which will be returned as-is. 

129 """ 

130 # If it's a model, use get_absolute_url() 

131 if hasattr(to, "get_absolute_url"): 

132 return to.get_absolute_url() 

133 

134 if isinstance(to, Promise): 

135 # Expand the lazy instance, as it can cause issues when it is passed 

136 # further to some Python functions like urlparse. 

137 to = str(to) 

138 

139 # Handle relative URLs 

140 if isinstance(to, str) and to.startswith(("./", "../")): 

141 return to 

142 

143 # Next try a reverse URL resolution. 

144 try: 

145 return reverse(to, args=args, kwargs=kwargs) 

146 except NoReverseMatch: 

147 # If this is a callable, re-raise. 

148 if callable(to): 

149 raise 

150 # If this doesn't "feel" like a URL, re-raise. 

151 if "/" not in to and "." not in to: 

152 raise 

153 

154 # Finally, fall back and assume it's a URL 

155 return to