Advertisement
horozov86

get_context_data & get_queryset

Sep 16th, 2024 (edited)
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.05 KB | None | 0 0
  1. class FilterTodoForm(forms.Form):
  2.     title_pattern = forms.CharField(
  3.         max_length=Todo.MAX_TITLE_LENGTH,
  4.         required=False,
  5.     )
  6.  
  7.     is_done = forms.BooleanField(
  8.         required=False,
  9.     )
  10.  
  11.  
  12. class ListTodoView(views.ListView):
  13.     model = Todo
  14.     template_name = "web/list_todo.html"
  15.  
  16.  
  17.     def get_context_data(self, **kwargs):
  18.         context = super().get_context_data(**kwargs)
  19.  
  20.         context["title"] = "Todos list"
  21.  
  22.         context["filter_form"] = FilterTodoForm(
  23.             initial={
  24.                 "title_pattern": self.get_title_pattern(),
  25.             },
  26.         )
  27.         return context
  28.  
  29.     def get_queryset(self):
  30.         queryset = super().get_queryset()
  31.         queryset = self.apply_filter(queryset)
  32.         return queryset
  33.  
  34.     def apply_filter(self, queryset):
  35.         title_pattern = self.get_title_pattern()
  36.         if title_pattern:
  37.             queryset = queryset.filter(title__icontains=title_pattern)
  38.  
  39.  
  40.         return queryset
  41.  
  42.     def get_title_pattern(self):
  43.         return self.request.GET.get("title_pattern", None)
  44.  
  45.     def get_is_done_filter(self):
  46.         return self.request.GET.get("is_done", None) == 'on'
  47.  
  48. Когато override-нем метода get_context_data, можем да добавяме допълнителни данни в контекста, които след това да се визуализират в нашия template.
  49.  
  50. Например, когато в template-а използваме {{ title }} (идващо от context["title"] = "Todos list"), на страницата ще се визуализира текстът "Todos list".
  51.  
  52. Филтрация чрез формата:
  53.  
  54. Създаваме форма FilterTodoForm, която съдържа полетата title_pattern и is_done за филтриране на задачите по заглавие и статус (завършена/незавършена).
  55.  
  56. В метода get_queryset(self) се осъществява филтрирането:
  57.  
  58. Първо, извикваме основния queryset чрез super().get_queryset(), който ни връща всички задачи по подразбиране.
  59. След това извикваме метода apply_filter, който прилага необходимите филтри върху този queryset.
  60. В метода apply_filter(self, queryset):
  61.  
  62. Извикваме метода get_title_pattern() за да получим въведеното заглавие за търсене.
  63. Ако има въведен текст в полето за търсене (title_pattern), се филтрират задачите, чието заглавие съдържа този текст (title__icontains=title_pattern).
  64. Методът get_is_done_filter(self) връща дали полето is_done е маркирано (взема информацията от заявката GET).
  65.  
  66. Ако има въведени критерии за филтрация (например заглавие или статус), те се прилагат чрез метода apply_filter.
  67.  
  68. Визуализация на формата:
  69.  
  70. За да визуализираме формата на страницата, добавяме я в контекста чрез context["filter_form"]. Например:
  71.  
  72. context["filter_form"] = FilterTodoForm(
  73.     initial={
  74.         "title_pattern": self.get_title_pattern(),
  75.     }
  76. )
  77.  
  78. Чрез параметъра initial можем да запазим въведените данни във формата след натискане на бутона за търсене. Така ако потребителят търси по определени думи или статус, тези критерии ще останат визуализирани във формата след изпълнение на заявката.
  79.  
  80. Ако потребителят маркира checkbox-а в HTML формата, при изпращане на заявката параметърът is_done ще има стойност 'on'. Това е стандартното поведение на HTML формите за checkbox полета – когато checkbox е маркиран, името на полето се изпраща със стойност 'on'.
  81.  
  82. За да проверим дали checkbox-ът е маркиран, използваме следния код:
  83.  
  84. self.request.GET.get("is_done", None) == 'on'
  85.  
  86. Това сравнение проверява дали параметърът is_done е равен на 'on'. Ако checkbox-ът е маркиран, ще получим True, тъй като is_done е изпратено със стойност 'on'. Ако не е маркиран, is_done изобщо няма да бъде изпратено в заявката, и методът .get("is_done", None) ще върне None, което води до False.
  87.  
  88. Затова добавяме == 'on' — за да проверим дали checkbox-ът е активен или не.
  89.  
  90.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement