How do I create an advanced custom search form in django admin and use django admins change view list

advertisements

How can I create an advanced custom search form in Django admin and use Django admins change list display. My advanced search form has several fields, including:

  • region
  • city
  • province

admin.py:

class PropertyAdmin(ModelAdmin):
    change_list_template = "property/admin/property_change_list.html"
    list_per_page = 20
    list_display_links = ('property_country_province_city',)
    search_fields = ('id',)
    list_filter = ('is_sale','is_rent','is_presales','estate_type','water')
    list_display_links = ('property_type',)

Models.py

class Property(models.Model):
    objects = PublicPropertyManager()
    title = models.CharField(_("title"), max_length = 80, blank=True)
    country = models.ForeignKey(Country, verbose_name=_("Country"))
    province = models.ForeignKey(Province, verbose_name=_("Province"))
    city = models.ForeignKey(City, verbose_name=_("City"))
    region = models.ForeignKey(Region, verbose_name=_("Region"))
    address = models.CharField(
        verbose_name=_("address"), max_length = 250, blank=True, null=True
    )


class CandidateAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.TextField: {'widget': Textarea(attrs={'rows': 4, 'cols': 40})},
    }
    list_display = ('id', 'first_name', 'last_name', 'current_company',
                    'title', 'gender', 'country', 'status', 'consultant',
                    'mobile_number', 'civil_reg_number', 'added_date')
    list_display_links = ('id', 'first_name', 'last_name')
    list_filter = ('consultant', 'status', 'gender', 'country', 'city')
    form = CandidateForm
    advanced_search_form = AdvancedSearchForm()
    other_search_fields = {}
    search_fields = ['first_name', 'last_name', 'civil_reg_number',
                     'status', 'cvmn', 'cven',
                     'address', 'mobile_number', 'notes']
    actions = [recruited_by_scc]

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'consultant':
            kwargs['initial'] = Consultant.objects.get(user=request.user)
            return db_field.formfield(**kwargs)
        return super(CandidateAdmin, self).\
            formfield_for_foreignkey(db_field, request, **kwargs)

    def changelist_view(self, request, extra_context=None, **kwargs):
        extra_context = {'asf':self.advanced_search_form}
        request.POST._mutable=True
        post_keys = []
        search_keys = []
        for key in request.POST.keys():
            value=request.POST.get(key)
            if value!='' and key!='csrfmiddlewaretoken':
                post_keys.append(key)
        for key in self.other_search_fields.keys():
            value = [x for x in self.other_search_fields.get(key) if x!='']
            if value:
                search_keys.append(key)
        if post_keys!=search_keys and len(post_keys)>0 and len(search_keys)>0:
            self.other_search_fields = {}
        for key in self.advanced_search_form.fields.keys():
            try:
                temp = request.POST.pop(key)
            except KeyError:
                pass
            else:
                if temp!=['']:
                    self.other_search_fields[key] = temp
        request.session[request.user.username] = self.other_search_fields
        self.other_search_fields = {}
        request.POST._mutable=False
        return super(CandidateAdmin, self).changelist_view(request, extra_context=extra_context)

    def queryset(self, request):
        qs = super(CandidateAdmin, self).queryset(request)
        search_query = []
        #self.other_search_fields = request.session[request.user.username]
        if request.session[request.user.username]:
            other_search_fields = request.session[request.user.username]
            for key in other_search_fields.keys():
                key_values = other_search_fields.get(key)
                key_values =[value for value in key_values if value!='']
                if key_values:
                    questions = [('{0}__icontains'.format(key), value) for value in key_values]
                    q_list = [Q(x) for x in questions]
                    query = reduce(operator.or_, q_list)
                    search_query.append(query)
            if search_query:
                make_query = reduce(operator.and_, search_query)
                return qs.filter(make_query)
        return qs

admin/search_form.html

   {% load i18n grp_tags %}
    {% if cl.search_fields %}
        <!-- Search Form -->
        {% if asf %}
        <form action="" method="POST"> {% csrf_token %}
            {{asf}}
            <input type="submit" value="search" />
        </form>
        {% else %}
         <!-- Search Form -->
         <form id="grp-changelist-search" action="" method="get">
             <input type="text" name="{{ search_var }}" id="grp-changelist-search" class="grp-search-field" value="{{ cl.query }}" />
             <button type="submit" value="" class="grp-search-button"></button>
             {% for pair in cl.params.items %}
                 {% ifnotequal pair.0 search_var %}<input type="hidden" name="{{ pair.0 }}" value="{{ pair.1 }}"/>{% endifnotequal %}
             {% endfor %}
         </form>
        {% endif %}
    {% endif %}