2014-04-03 47 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') 

因此,添加时,我们简单地忽略事件(登记保存清零事件),然后,在改变事件的列表可以根据选择之前定义的研讨会被忽略(因为我们无法重新载入相关事件列表)。