Django管理多个子集

时间:2014-04-03 13:50:42

标签: python django django-models django-forms django-admin

我正在尝试将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上的Event M2M适当的还是我应该以不同的方式将这两个模型联系起来?

谢谢!

1 个答案:

答案 0 :(得分: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')

因此,在添加时我们只是忽略事件(注册是用无效事件保存的)然后,在更改时,可以根据先前定义的研讨会选择事件列表,然后忽略(因为我们无法重新加载)相关事件清单)。