1

为了将选择限制在当前用户的集合中,您必须执行以下操作:

class ChoiceForm(forms.ModelForm):
    def __init__(self, user, *args, **kwargs):
        super(ChoiceForm, self).__init__(*args, **kwargs)
        self.fields['poll'].queryset = Poll.objects.filter(owner=user)

    class Meta:
        model = Choice

根据项目的大小,这可能会变得非常重复。另外,您最终不得不为管理表单做同样的事情。有可能避免这种情况吗?

4

1 回答 1

1

使用通用视图并定义一个get_form将用户添加到表单的 kwargs 的方法,然后创建一个接受额外userkwarg 的自定义基表单类,如下所示:

形式

class UserModelForm(ModelForm):
    """
    Base form class with user-based FK filtering.
    """
    def __init__(self, *args, **kwargs):
        """
        Filters the queryset on foreign keys to limit to the provided user.
        """
        # Pop the user from the kwargs
        user = kwargs.pop('user')

        # Delegate initilization to super using the remaining args and kwargs
        super(UserModelForm, self).__init__(*args, **kwargs)

        self.prepare_for_user(user)

    def prepare_for_user(self, user):
        """
        Handles user related setup - for use inside __init__ - abstracted
        from __init__ to make testing easier.
        """
        # Get the user's PK
        user_pk = user.pk

        # Filter foriegn key fields to records owned by the user

        # Make a generator of the form's FK fields
        fks = [f for f in self.fields.itervalues() if hasattr(f, 'queryset')]

        # Iterate the FK fields and filter them - you might want to check
        # for something like `if hasattr(field.queryset.model, 'user'):`, etc.
        for field in fks:
            field.queryset = field.queryset.filter(user_id=user_pk)

看法

class MyView(object):
    """
    A mixin for views.
    """
    def get_form(self, form_class):
    """
    Returns the provided form class, instantiated with the form kwargs,
    adding a user kwarg.
    """
    # Create some form kwargs with the user included
    defaults = {'user': self.request.user}

    # Update the kwargs with the default form kwargs
    defaults.update(self.get_form_kwargs())

    return form_class(**defaults)
于 2013-05-30T00:53:24.150 回答