如何在Django应用程序中正确分组mixins?

时间:2015-11-24 10:43:11

标签: django design-patterns django-views mixins

初始情况

我有一个应用程序,'设备'有一些观点:

class DeviceUpdateView(LoginRequiredMixin, UpdateView):
    model = Device
    form_class = DeviceEditForm

    def get_form(self, form_class=None):
        form = super(DeviceUpdateView, self).get_form(form_class=None)
        form.fields['beacon'].queryset=Beacon.objects.filter(customer_account=self.request.user.default_customer_account)
        return form

class DeviceCreateView(LoginRequiredMixin, CreateView):
    model = Device
    form_class = DeviceEditForm

    def get_initial(self):
        initial = super(DeviceCreateView, self).get_initial()
        initial['customer_account'] = self.request.user.default_customer_account
        return initial

    def get_form(self, form_class=None):
        form = super(DeviceCreateView, self).get_form(form_class=None)
        form.fields['beacon'].queryset=Beacon.objects.filter(customer_account=self.request.user.default_customer_account)
        return form

我有另一个应用程序(' buildings')vith这个观点:

class BuildingCreateView(LoginRequiredMixin, UserFormKwargsMixin, CreateView):
    model = Building
    form_class = BuildingEditModelForm

    def get_initial(self):
        initial = super(BuildingCreateView, self).get_initial()
        initial["customer_account"] = self.request.user.default_customer_account
        return initial

DRY Mixin

现在,我想将我的代码分解为更多" DRY"。

然后我在我的devices / views.py中创建了这个mixin:

class BeaconFilterMixin(object):
    def get_form(self, form_class=None):
        form = super(BeaconFilterMixin, self).get_form(form_class=None)
        form.fields['beacon'].queryset=Beacon.objects.filter(customer_account=self.request.user.default_customer_account)
        return form

我的观点变成了:

class DeviceUpdateView(LoginRequiredMixin, BeaconFilterMixin, UpdateView):
    model = Device
    form_class = DeviceEditForm


class DeviceCreateView(LoginRequiredMixin, BeaconFilterMixin, CreateView):
    model = Device
    form_class = DeviceEditForm

    def get_initial(self):
        initial = super(DeviceCreateView, self).get_initial()
        initial['customer_account'] = self.request.user.default_customer_account
        return initial

很好,很甜蜜!

现在问题

我想做同样的事情并创建一个" InitialCustomerAccountMixin"这两个建筑物都可以使用这些建筑物。和'设备'应用

代码将是:

class InitialCustomerAccountMixin(object):
    def get_initial(self):
        initial = super(InitialCustomerAccountMixin, self).get_initial()
        initial['customer_account'] = self.request.user.default_customer_account
        return initial

问题是:我在哪里放置我的mixins代码? 对于“应用范围”' mixin,我知道我应该将代码放在views.py或app中的mixins.py文件中。 但对于一个多应用程序来说mixin,我不知道要遵循的设计原则。

1 个答案:

答案 0 :(得分:0)

您应该遵循功能分组原则(或任何您称之为的原则)。

如果您的应用中有UI图层,则应该有Mixins模块(包,命名空间或其他)。该模块应具有所有mixins使用的类别:Auth,Filter,View,...等。每个类别应包含受尊重的mixins。

这适用于单应用混音。

Mixins,你必须在你的应用程序之间共享应该封装到他们自己的模块(或任何Python可重用的包被调用)。这个模块应该是私密的,应该适当调用,并且应该分成合理的类别。