Thursday, 29 April 2021

Optimize multiple Views to one View - Django

I am using django-autocomplete-light widget for loading data dynamically to display in the HTML forms.

I want to optimize below urls to one url and its views classes to single view as most of the code(90% code) is common across all the views, only few parameters are different.

Here is my 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'),

Here are its Views from 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

I was trying something like this, but not sure how can I pass other relevant parameters such as database query parameters, model name, etc.

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

Can anyone help me to optimize above code?



from Optimize multiple Views to one View - Django

No comments:

Post a Comment