Django Ajax Method Caller для потрясающих вызовов Ajax с помощью динамического импорта
Всем привет. В этой статье я собираюсь написать о методе, который я увидел, когда был стажером-разработчиком в проекте erp, написанном на PHP. Я реализовал этот хитрый метод на Python, чтобы использовать его в своем проекте Django. Я буду писать о том, как мы можем собрать части, вместо того, чтобы подробно рассказывать о том, что такое importlib и т. д.
Короче говоря, этот метод вызывает методы в классах, используя строковые пути, и передает параметры, если они есть. Используя этот метод, я могу легко использовать вызовы AJAX и обмениваться данными между интерфейсом и сервером. Это уменьшает количество создания представлений для обработки запросов.
Помощники: класс DynamicImporter и функция get_ajax_result_dict
По сути, класс DynamicImporter имеет 2 метода: import_module и import_class.
# helpers/dynamic_importer.py import importlib class DynamicImporter: def import_module(self, module_name): return importlib.import_module(module_name) def import_class(self, module_name, class_name): module = self.import_module(module_name) return getattr(module, class_name)
Мы можем присвоить класс переменной, используя метод: DynamicImporter().import_class("apps.book.models", "Book")
. Для этого мы используем importlib
, который является встроенным пакетом Python.
У меня также есть еще одна вспомогательная функция, get_ajax_result_dict
, которую я использую для создания ответа dict. Это просто стандарт для унификации ответов и упрощения их поиска.
# helpers/http.py def get_ajax_result_dict( result="false", msg="This is default message!", additional_data=None ): """ We use this function in all JSONResponse functions to unify responses result (str): Response flag, true | false msg (str): Response message additional_data (dict): Extra data for result dict """ result = {"result": result, "msg": msg} if additional_data is not None: result.update(additional_data) return result
Представление вызывающего метода и URL-адрес
Представление ниже сталкивается с запросами ajax, и мы всегда отправляем наш запрос ajax этому представлению. Это представление сначала создает экземпляр класса, а затем присваивает его метод переменной для вызова. Мы используем представление ниже, используя функцию JavaScript в следующем разделе.
# views.py @csrf_exempt # from django.views.decorators.csrf import csrf_exempt (optional, you can handle the csrf token with js) def ajax_method_caller(request): if request.method == "POST": module_name = request.POST.get("module_name") class_name = request.POST.get("class_name") method_name = request.POST.get("method_name") args = request.POST.getlist("args[]") importer = DynamicImporter() try: target_class = importer.import_class(module_name, class_name) instance = target_class() method = getattr(instance, method_name) result = method(*args) return JsonResponse(get_ajax_result_dict("true", "SUCCESS!", {"result": result})) except Exception as e: return JsonResponse(get_ajax_result_dict("false", str(e), {"result": None})) return JsonResponse(get_ajax_result_dict("false", "Request error!"))
Вы можете спросить, почему вы переопределяете «результат» в ответе об успехе 🥲 Это зависит от вашего использования, вы можете реализовать все, что хотите.
Его простой URL.
# urls.py urlpatterns.append(path("ajax-method-caller/", views.ajax_method_caller, name="ajax_method_caller"))
Вызывающий метод JavaScript
Приведенная ниже функция отправляет запрос POST в представление ajax_method_caller
.
// helpers.js // it requires JQuery const ajax_method_caller = ( module_name, class_name, method_name, args, success_func, err_func ) => { /* * module_name: module name of the method * class_name: class name of the method * method_name: method name to be called * args: arguments to be passed to the method * success_func: function to be called on success * err_func: function to be called on error */ $.ajax({ url: "/ajax-method-caller/", type: "POST", data: { 'module_name': module_name, 'class_name': class_name, 'method_name': method_name, 'args': args }, success: success_func, error: err_func, }); }
Прикладной пример метода
Вы можете увидеть пример применения метода ниже. Теперь вы можете легко использовать свои классы Python, вызывая их из внешнего интерфейса.
ajax_method_caller("apps.datagateway.models", "DataTable", "apply_column_action", [action_type, pk], // these are defined in the template (res) => { // success response get_card_notification(res.result); location.reload(); }, (err) => { // error response get_card_notification(err.msg); });
Окончательно
Надеюсь, это было полезно, и вам понравилось. Вы можете получить доступ к коду, используя Gist ниже.
С уважением