ModelChoiceFields的工厂

时间:2014-12-19 12:41:08

标签: python django customization factory-pattern

我有两个客户使用我的django应用程序fooapp

  • Customer1希望用户的ChoiceFields排序依据('username','last_name','first_name')
  • Customer2希望用户的ChoiceFields排序依据('last_name','first_name')

我不想将客户特定代码放入fooapp

如何以客户喜欢的方式显示应用程序中的所有UserChoiceField?

一个简单的解决方案是像USER_CHOICE_ORDER_BY这样的设置。但迟早会有更多困难的事情需要。然后我可以使用带有导入字符串的设置USER_CHOICE_FIELD

让我们退后一步,看看它。将所有 ModelChoiceFields重定向到自定义字段会不会很好?

示例:一般解决方案适用于User,Group,...所有模型(提供我的django或由第三方提供)。

有没有这样的东西?

2 个答案:

答案 0 :(得分:0)

如@DRC所述,您应该使用受影响的模型中的order_by Meta属性。为了确保您没有任何客户特定代码,请在您的settings.py文件中添加此代码,如下所示:

MODEL_ORDER_BY = {
    'User':['username', 'last_name', 'first_name']
}

然后在models.py文件中,您可以这种方式引用这些值:

来自django.conf导入设置

Class User
    class Meta():
        # Making sure we have a settings value for this model first
        if self.__name__ in settings.MODEL_ORDER_BY:
            # Setting the list that's paired with this name
            order_by = settings.MODEL_ORDER_BY[self.__name__]

答案 1 :(得分:0)

您可以将一个UserChoiceSortItem模型添加到fooapp,并保持其他模型按此模型的对象排序优先级:

class UserChoiceSortItem(models.Model):
    _models = [
        (0, 'Profiles'),
        (1, 'Groups'),
        .
        .
        .
    ]
    sort_field = models.CharField(max_length=200)
    priority = models.IntegerField()
    model = models.IntegerField(choices=_models)
    _model_type = None        

    @property
    def model_class(self):
      if self._model_type is None:
        from django.apps import apps
        _models = ['fooapp.CustomProfile', 'django.contrib.auth.Group', ...]
        self._model_type = apps.get_model(*_models[self.model].rsplit('.', 1))
      return self._model_type

然后您可以在视图或表单中使用UserChoiceSortItems模型的对象:

.
.
.
order_fields = []
for sort_item in UserChoiceSortItems.objects.all().order_by('priority'):
    if isinstance(curent_model_objects, sort_items.model_class):
        order_fields.append(sort_item)
curent_model_objects.order_by(*order_fields)
choice_field.choices = order_fields
.
.
.

你也可以在fooapp中使用 fixtures 为不同的客户启动不同的状态(例如,对于第一个客户fooapp / fixtures / customer1.json):

[
    {
        'pk': 1,
        'model': 'fooapp.UserChoiceSortItems',
        'fields': {
            'sort_field': 'username',
            'priority': 0,
            'model': 'fooapp.CustomProfile'
        }
    },
    {
        'pk': 2,
        'model': 'fooapp.UserChoiceSortItems',
        'fields': {
            'sort_field': 'first_name',
            'priority': 1,
            'value': 'fooapp.CustomProfile'
        }
    },
    {
        'pk': 3,
        'model': 'fooapp.UserChoiceSortItems',
        'fields': {
            'sort_field': 'last_name',
            'priority': 2,
            'model': 'fooapp.CustomProfile'
        }
    },
    .
    .
    .
]

和第二个客户fooapp / fixtures / customer2.json:

[
    {
        'pk': 1,
        'model': 'fooapp.UserChoiceSortItems',
        'fields': {
            'sort_field': 'first_name',
            'priority': 0,
            'model': 'fooapp.CustomProfile'
        }
    },
    {
        'pk': 2,
        'model': 'fooapp.UserChoiceSortItems',
        'fields': {
            'sort_field': 'last_name',
            'priority': 1,
            'value': 'fooapp.CustomProfile'
        }
    },
    .
    .
    .
]

并在syncdb之后,您可以通过以下命令加载数据。

customer1表:

./manage.py loaddata customer1

的customer2:

./manage.py loaddata customer2

您和您的客户可以在django-admin和ENJOY上编辑排序优先级...