python - 将多个视图优化为一个视图 - Django
问题描述
我正在使用django-autocomplete-light 小部件动态加载数据以显示在 HTML 表单中。
我想将以下 url 优化为一个 url,并将其视图类优化为单个视图,因为大多数代码(90% 代码)在所有视图中都是通用的,只有少数参数不同。
这是我的urls.py
:
path('locations/', views.LocationAutocomplete.as_view(), name='location-autocomplete'),
path('societies/', views.SocietyAutocomplete.as_view(), name='society-autocomplete'),
path('propcats/', views.PropertyCategoryAutocomplete.as_view(), name='propcat-autocomplete'),
...
path('projects/', views.ProjectAutocomplete.as_view(), name='project-autocomplete'),
以下是其观点views.py
:
class LocationAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not self.request.user.is_authenticated:
return Location.objects.none()
qs = Location.objects.all()
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs
class SocietyAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not self.request.user.is_authenticated:
return Society.objects.none()
preferred_area = self.forwarded.get('preferred_area', None)
qs = Society.objects.filter(location_id__in=preferred_area)
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs
class PropertyCategoryAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not self.request.user.is_authenticated:
return PropertyCategory.objects.none()
enquiry_flag = self.request.session.get('enquiry_flag', 3)
qs = PropertyCategory.objects.filter(type__enq_code = enquiry_flag)
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs
class FloorAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not self.request.user.is_authenticated:
return Floor.objects.none()
qs = Floor.objects.all()
if self.q:
qs = qs.filter(floor__istartswith=self.q)
return qs
class ProjectAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not self.request.user.is_authenticated:
return Project.objects.none()
qs = Project.objects.all()
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs
我正在尝试这样的事情,但不确定如何传递其他相关参数,例如数据库查询参数、模型名称等。
class AutoCompleteHandler(autocomplete.Select2QuerySetView):
def __init__(self, model, model_query, *args, **kwargs):
super().__init__(*args, **kwargs)
self.model = model
self.model_query = model_query
def get_queryset(self):
if not self.request.user.is_authenticated:
return self.model.objects.none()
enquiry_flag = self.request.session.get('enquiry_flag', 1)
qs = self.model.objects.filter(**self.model_query)
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs
谁能帮我优化上面的代码?
解决方案
class GenericModelAutoComplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not seslf.request.user.is_authenticated:
return self.model.objects.none()
qs = self.qs or self.get_qs()
return self._get_queryset().filter(name__istartswith=self.q)
class FloorAutocomplete(GenericModelAutoComplete):
qs = Floor.objects.all()
class PropertyAutocomplete(GenericModelAutoComplete):
def get_qs(self):
enquiry_flag = self.request.session.get('enquiry_flag', 3)
return PropertyCategory.objects.filter(type__enq_code = enquiry_flag)
依此类推,并且使用相同的网址。可选地,有这个:https ://github.com/isik-kaplan/django-urls
您可以使用它来简化您的 url 如何与您的视图一起使用。
from django_urls import UrlManager
autocomplete = UrlManager()
class GenericModelAutoComplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not seslf.request.user.is_authenticated:
return self.model.objects.none()
qs = self.qs or self.get_qs()
return self._get_queryset().filter(name__istartswith=self.q)
def __init_subclass__(self, **kwargs):
# Automatically adds the view to autocomplete urlpatterns
cls = self.__class__
autocomplete.path(name=f"{cls.endpoint}-autocomplete")(cls)
return super().__init_subclass__(**kwargs)
class FloorAutocomplete(GenericModelAutoComplete):
qs = Floor.objects.all()
class PropertyAutocomplete(GenericModelAutoComplete):
def get_qs(self):
enquiry_flag = self.request.session.get('enquiry_flag', 3)
return PropertyCategory.objects.filter(type__enq_code = enquiry_flag)
# urls.py
from .views import autocomplete
urlpatterns = autocomplete.url_patterns
第二个版本在基本视图中只长了 4-5 行,但它使您不必为每个视图编写新的 url 模式。
推荐阅读
- http-live-streaming - OBS - m3u8 文件中列出的 TS 文件数量增加
- python - 为什么我不能使用 PIL 将我从 WebP 下载的图像转换为 JPG?
- python - python超类可以从其子类调用函数吗?
- python - Google 图书 API 作者
- r - 将两个数据框与公共列连接在一起
- reactjs - Stripe 应该集成在前端还是后端?(反应+Django 休息)
- vb.net - 与主表单中的“标签”属性一起使用时,类列表会出错
- javascript - React Native Navigator Stack Screen 选项未定义?
- javascript - 在循环中计算分数的总和
- python - 气流 - alembic.util.exc.CommandError:找不到由“a13f7613ad25”标识的修订版