formsbuttons.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. from django.contrib import messages
  2. from django.db import transaction
  3. from django.shortcuts import redirect
  4. from .base import AdminView
  5. class TargetedView(AdminView):
  6. is_atomic = True
  7. def check_permissions(self, request, target):
  8. pass
  9. def get_target(self, kwargs):
  10. if len(kwargs) == 1:
  11. select_for_update = self.get_model().objects
  12. if self.is_atomic:
  13. select_for_update = select_for_update.select_for_update()
  14. # Does not work on Python 3:
  15. # return select_for_update.get(pk=kwargs[kwargs.keys()[0]])
  16. (pk, ) = kwargs.values()
  17. return select_for_update.get(pk=pk)
  18. else:
  19. return self.get_model()()
  20. def get_target_or_none(self, request, kwargs):
  21. try:
  22. return self.get_target(kwargs)
  23. except self.get_model().DoesNotExist:
  24. return None
  25. def dispatch(self, request, *args, **kwargs):
  26. if self.is_atomic:
  27. with transaction.atomic():
  28. return self.wrapped_dispatch(request, *args, **kwargs)
  29. else:
  30. return self.wrapped_dispatch(request, *args, **kwargs)
  31. def wrapped_dispatch(self, request, *args, **kwargs):
  32. target = self.get_target_or_none(request, kwargs)
  33. if not target:
  34. messages.error(request, self.message_404)
  35. return redirect(self.root_link)
  36. error = self.check_permissions(request, target)
  37. if error:
  38. messages.error(request, error)
  39. return redirect(self.root_link)
  40. return self.real_dispatch(request, target)
  41. def real_dispatch(self, request, target):
  42. pass
  43. class FormView(TargetedView):
  44. form = None
  45. template = 'form.html'
  46. def create_form_type(self, request):
  47. return self.form
  48. def initialize_form(self, form, request):
  49. if request.method == 'POST':
  50. return form(request.POST, request.FILES)
  51. else:
  52. return form()
  53. def handle_form(self, form, request):
  54. raise NotImplementedError(
  55. "You have to define your own handle_form method to handle "
  56. "form submissions."
  57. )
  58. def real_dispatch(self, request, target):
  59. FormType = self.create_form_type(request)
  60. form = self.initialize_form(FormType, request)
  61. if request.method == 'POST' and form.is_valid():
  62. response = self.handle_form(form, request)
  63. if response:
  64. return response
  65. elif 'stay' in request.POST:
  66. return redirect(request.path)
  67. else:
  68. return redirect(self.root_link)
  69. return self.render(request, {'form': form})
  70. class ModelFormView(FormView):
  71. message_submit = None
  72. def create_form_type(self, request, target):
  73. return self.form
  74. def initialize_form(self, form, request, target):
  75. if request.method == 'POST':
  76. return form(request.POST, request.FILES, instance=target)
  77. else:
  78. return form(instance=target)
  79. def handle_form(self, form, request, target):
  80. form.instance.save()
  81. if self.message_submit:
  82. format = {'name': target.name}
  83. messages.success(request, self.message_submit % format)
  84. def real_dispatch(self, request, target):
  85. FormType = self.create_form_type(request, target)
  86. form = self.initialize_form(FormType, request, target)
  87. if request.method == 'POST' and form.is_valid():
  88. response = self.handle_form(form, request, target)
  89. if response:
  90. return response
  91. elif 'stay' in request.POST:
  92. return redirect(request.path)
  93. else:
  94. return redirect(self.root_link)
  95. return self.render(request, {'form': form, 'target': target})
  96. class ButtonView(TargetedView):
  97. def real_dispatch(self, request, target):
  98. if request.method == 'POST':
  99. new_response = self.button_action(request, target)
  100. if new_response:
  101. return new_response
  102. return redirect(self.root_link)
  103. def button_action(self, request, target):
  104. raise NotImplementedError("You have to define custom button_action.")