簡體   English   中英

如何在django admin中創建高級自定義搜索表單並使用django管理員更改列表顯示

[英]how can i create advanced custom search form in django admin and use django admins change list display

如何在Django管理員中創建高級自定義搜索表單並使用Django管理員更改列表顯示。 我的高級搜索表單有幾個字段,包括:

  • 區域

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

管理員/ 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 %}

我不確定你是否意味着你已經編寫了自定義搜索,但在這種情況下,根據你想做的事情,你可能不需要那樣做。 您可以通過默認的search_fields搜索相關的模型字段,但需要注意這將生成相關的查找/連接。

我不確定CityProvinceRegion什么樣的,但假設他們有一個name字段,這應該有效(如果他們有一個id字段,這只是province__id ,等等):

# admin.py

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

請注意,如果您在list_display呈現任何ForeignKeys ,您可能希望覆蓋查詢集以在您顯示的任何字段上使用select_related ,以避免生成大量不必要的SQL查詢:

# 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它看起來像你在那里定義了list_display_links兩次,所以第二個定義覆蓋了第一個定義,這可能不是你想要的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM