2013-05-21 42 views
6

我有一個模型,看起來像這樣:限制了多對多MultipleSelect的查詢集在Django管理

class Event(models.Model): 
    event_dates = ManyToManyField("EventDate") 
    #... 

class EventDate(models.Model): 
    event_date = DateField() 
    #... 

然而,在獲取顯示在EventAdmin event_dates Django管理MultipleSelect表單字段,我想將查詢集限制爲不在過去的event_dates。

的查詢集將是這樣的:

event_date_queryset = EventDate.objects.filter(event_date__gte = datetime.date.today()) 

但我在哪裏可以設置此查詢集,以便只有非過去的日期在現場露面?

(我目前沒有爲EventAdmin自定義表單,但會很樂意添加一個。)

+0

[在Django管理篩選多對多盒(HTTP的可能重複:// stackoverflow.com/questions/1226760/filter-manytomany-box-in-django-admin) – Wtower

回答

14

你可以嘗試:從https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.limit_choices_to

但隨後採取

event_dates = models.ManyToManyField("EventDate", limit_choices_to={'event_date__gte': date.today()}) 

僅顯示未來的日期,即使過去的某些日期仍與Event相關聯。

如果你也想你以前關聯到Event所有的約會,你可以操縱ModelForm如下

from datetime import date 

from django.contrib import admin 
from django import forms 
from django.db.models import Q 

from models import Event, EventDate 

class EventAdminForm(forms.ModelForm): 
    class Meta: 
     model = Event 

    def __init__(self, *args, **kwargs): 
     super(EventAdminForm, self).__init__(*args, **kwargs) 
     if 'event_dates' in self.initial: 
      self.fields['event_dates'].queryset = EventDate.objects.filter(Q(pk__in=self.initial['event_dates']) | Q(event_date__gte=date.today())) 
     else: 
      self.fields['event_dates'].queryset = EventDate.objects.filter(event_date__gte=date.today()) 

class EventAdmin(admin.ModelAdmin): 
    form = EventAdminForm 
    filter_horizontal = ['event_dates'] 
+0

是的,我的意思是event_dates並更新了問題,以準確反映這一點。希望保留過去已經選擇的event_dates的好點。儘管我通過limit_choices_to瞭解了一些新的東西,但更完整的解決方案可能是我所追求的。謝謝! –

+0

我最後幾乎逐字逐句使用了第二種(更全面)的方法,效果很好。 –

2

簡單的方法就是做在管理

你的模型

class Event(models.Model): 
    event_dates = ManyToManyField("EventDate") 
    #... 

class EventDate(models.Model): 
    event_date = DateField() 
    #... 

現在,在你的管理文件

這有一個好處,它只返回日期的事件只爲你正在尋找使用反向查找當前事件event__id=event_id

class EventAdmin(admin.ModelAdmin): 
    def get_field_queryset(self, db, db_field, request): 
     """ 
     If the ModelAdmin specifies ordering, the queryset should respect that 
     ordering. Otherwise don't specify the queryset, let the field decide 
     (returns None in that case). 
     """ 
     if db_field.name == 'event_dates': 
      event_id = int(request.resolver_match.args[0]) 

      return db_field.remote_field.model._default_manager.filter(
           event__id=event_id, 
           event_date__gte = datetime.date.today() 
      ) 

     super().get_field_queryset(db, db_field, request)