2013-05-21 6 views
6

मैं एक मॉडल है कि इस तरह दिखता है:Django व्यवस्थापक में ManyToMany MultipleSelect के लिए क्वेरीसमूह सीमित

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 व्यवस्थापक में फ़िल्टर ManyToMany बॉक्स] (http के संभावित डुप्लिकेट: // stackoverflow.com/questions/1226760/filter-manytomany-box-in-django-admin) – Wtower

उत्तर

14

आप की कोशिश कर सकते:

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

से https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.limit_choices_to

लेकिन तब लिया भविष्य में केवल तिथियां दिखायी जाती हैं, भले ही अतीत में कुछ तिथियां अभी भी 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 था और प्रश्न को सटीक रूप से प्रतिबिंबित करने के लिए अद्यतन किया गया। ईवेंट_डेट्स को अतीत में रखना चाहते हैं, लेकिन पहले से ही चुना गया है पर अच्छा बिंदु। अधिक पूरा समाधान शायद वह है जिसके बाद मैं हूं, हालांकि मैंने 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) 
संबंधित मुद्दे