How can I create an advanced custom search form in django admin and use django admin list changelist

How to create an advanced custom search form in the Django admin and use the list of changes to the list of Django administrators. My advanced search form has several fields, including:

  • region
  • town
  • region

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 ) 
+5
source share
2 answers
 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 %} 
+2
source

I'm not sure if you meant that you already created a custom search, but in this case, depending on what you want to do, you might not need it. You can search the related fields of the default search_fields with the caveat that this will cause related queries / joins.

I'm not sure what City , Province and Region look like, but if they have a name field, this should work (if they have an id field, it's just province__id , etc.):

 # admin.py class PropertyAdmin(ModelAdmin): ... search_fields = ( 'region__name', 'city__name', 'province__name', ) 

Please note that if you edit any of the ForeignKeys in list_display , most likely you will want to override the query set to use select_related for any fields that you show so as not to generate a lot of unnecessary SQL queries:

 # admin.py class PropertyAdmin(ModelAdmin): ... def get_queryset(self, request); qs = super(PropertyAdmin, self).get_queryset(request) return qs.select_related('province', 'city', 'region',) 

PS It also looks like you define list_display_links twice, so the second definition overrides the first, which may not match the behavior you want.

0
source

Source: https://habr.com/ru/post/1269199/


All Articles