2014-04-03 50 views
1

我想在Django管理整合未來三年相關機型:Django管理多對多的子集

# models.py 
class Seminar(models.Model): 
    title = models.CharField(max_length=128, unique=True) 
    start_date = models.DateField(db_index=True) 
    end_date = models.DateField(db_index=True) 


class Event(models.Model): 
    title = models.CharField(max_length=128) 
    start_date = models.DateTimeField(db_index=True) 
    end_date = models.DateTimeField(db_index=True) 
    seminar = models.ForeignKey('Seminar') 


class Registration(models.Model): 
    name = models.CharField(max_length=128) 
    first_name = models.CharField(max_length=128) 
    seminar = models.ForeignKey('Seminar') 
    events = models.ManyToManyField('Event', null=True) 


# admin.py 
class EventInline(admin.TabularInline): 
    model = Event 


class SeminarAdmin(admin.ModelAdmin): 
    list_display = ('title', 'start_date', 'end_date') 
    inlines = [ 
     EventInline, 
    ] 


class RegistrationAdmin(admin.ModelAdmin): 
    list_display = ('seminar', 'name', 'first_name') 

正如你所看到的,每次研討會可能有幾個事件,從Seminar管理爲內聯添加條目。

我的問題是註冊的,因爲它們是:

  • 相關的研討會
  • 可以「訂閱」的這個研討會

當然幾個事件,管理員列出所有事件,而不是與研討會相關的子集,因此:

  • 是否可以從管理員(儘可能低的調整)實現這一點?
  • Registration M2M Event適當還是應該以不同的方式將這兩個模型關聯?

謝謝!

回答

1

那麼,就在問這裏之前,我通過使用不同的添加/更改視圖的表單,做了類似於Django的auth.User模型的一些操作。我希望有更好的解決方案,顯然不是。

因此,這裏是我做過什麼:

# models.py 
class Registration(models.Model): 
    # [...] - add form excludes it, should allow blank on events field 
    events = models.ManyToManyField('Event', blank=True, null=True) 


# admin.py 
class RegistrationAdmin(admin.ModelAdmin): 
    change_form = RegistrationChangeForm 

    def get_form(self, request, obj=None, **kwargs): 
     defaults = {} 
     if obj is None: 
      defaults.update(exclude=('events',)) 
     else: 
      defaults.update(form=self.change_form) 
     defaults.update(kwargs) 
     return super(RegistrationAdmin, self).get_form(request, obj, **defaults) 


# forms.py 
class RegistrationChangeForm(forms.ModelForm): 
    class Meta: 
     model = Registration 
     exclude = ('seminar',) 

    def __init__(self, *args, **kwargs): 
     super(RegistrationChangeForm, self).__init__(*args, **kwargs) 
     self.fields['events'].choices = Event.objects.filter(seminar=kwargs.get('instance').seminar).values_list('pk','title') 

因此,添加時,我們簡單地忽略事件(登記保存清零事件),然後,在改變事件的列表可以根據選擇之前定義的研討會被忽略(因爲我們無法重新載入相關事件列表)。