如何根据 request.user 限制对 Django 过滤器的选择

时间:2021-01-01 07:56:37

标签: django django-filters

我有一个多公司设置。用户登录到特定公司。每家公司都有自己的一套分类账账户和交易。在交易列表中,我创建了过滤器选项,以便用户可以根据“描述”、“交易日期”和“分类帐帐户”进行过滤。分类帐帐户的问题在于可用的选择是来自所有公司的帐户。我希望将选项限制为仅显示用户登录的当前公司的分类帐帐户。

用户模型

class custom_user(AbstractBaseUser):
    email                   = models.EmailField(verbose_name="email", max_length=60, unique=True)
    username                = models.CharField(max_length=30, unique=True)
    date_joined             = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
    last_login              = models.DateTimeField(verbose_name='last login', auto_now=True)
    is_admin                = models.BooleanField(default=False)
    is_active               = models.BooleanField(default=True)
    is_staff                = models.BooleanField(default=False)
    is_superuser            = models.BooleanField(default=False)
    company_group           = models.CharField(max_length=6, null=True)
    current_company         = models.ForeignKey(tcompany, on_delete=models.CASCADE, null=True)

注意 current_company 作为外键。

Leger 帐户模型

class tledger_account(models.Model):
    id = models.AutoField(primary_key=True)
    slug = models.SlugField(max_length=30, null=True)
    description = models.CharField(max_length=30, unique=False)
    gl_category = models.CharField(max_length=30, choices=category_choices, verbose_name='category', db_index=True)
    note = models.CharField(max_length=25, blank=True, default=None)
    active = models.BooleanField(default=True)
    company = models.ForeignKey(tcompany, on_delete=models.PROTECT)
    class Meta:
        indexes =[
            models.Index(fields=['company', 'description'])
        ]
        unique_together = ['company', 'description']

将公司记为外键。

Views.py

class TransactionlistView(ListView):
    model = ttransactions
    template_name = 'accounting/transaction_list.html'

    def get_form_kwargs(self):
        kwargs = super(TransactionlistView, self).get_form_kwargs()
        kwargs['request'] = self.request
        return kwargs

    def get_context_data(self, **kwargs):
        context = super(TransactionlistView, self).get_context_data(**kwargs)

        line_list = []
        context = {}
        balance = 0
        transactions = ttransactions.objects.order_by('transaction_date'). \
            filter(company=self.request.user.current_company)
        company = self.request.user.current_company

        transaction_count = transactions.count()
        myFilter = transactionFilter(self.request.GET, queryset=transactions, **kwargs)
        transactions = myFilter.qs
        transaction_lines_count = 0

        for transaction in transactions:
            transaction_lines = ttransaction_lines.objects.filter(transaction=transaction.id)

            transaction_lines_count = transaction_lines.count()
            mylineFilter = lineFilter(self.request.GET, queryset=transaction_lines)
            transaction_lines = mylineFilter.qs

            for transaction_line in transaction_lines:
                if transaction_line.transaction_type == 'Debit':
                    balance += transaction_line.amount
                else:
                    balance -= transaction_line.amount

                line = {
                    'transaction': transaction.id,
                    'description': transaction.description,
                    'transaction_date': transaction.transaction_date,
                    'sequence': transaction_line.sequence,
                    'transaction_type': transaction_line.transaction_type,
                    'ledger_account': transaction_line.ledger_account,
                    'amount': transaction_line.amount,
                    'balance': balance,
                }
                line_list.append(line)

        paginator = Paginator(line_list, 20)
        page = self.request.GET.get('page')
        try:
            line_list = paginator.page(page)
        except PageNotAnInteger:
            line_list = paginator.page(1)
        except EmptyPage:
            line_list = paginator.page(paginator.num_page)

        context = {'line_list': line_list, 'myFilter': myFilter, 'transactions': transactions,
                   'transaction_count': transaction_count, 'transaction_lines_count': transaction_lines_count,
                   'mylineFilter': mylineFilter, 'transaction_lines': transaction_lines, 'page': page}

        return context

Filter.py

class lineFilter(django_filters.FilterSet):
    legder_account = django_filters.ModelChoiceFilter(queryset=tledger_account.objects.filter(
        company=request.user.current_company))

    class Meta:
        model = ttransaction_lines
        fields = '__all__'
        exclude = ['transaction', 'sequence', 'quantity', 'posted', 'transaction_type', 'company', 'ledger_account']

这个设置给了我一个错误:"name 'request' is not defined" 问题是如何让 request.user 到 filter.py

1 个答案:

答案 0 :(得分:0)

您可以这样尝试(基于 documentation 中的示例):

def accounts(request):
    if request is None:
        return tledger_account.objects.none()
    return tledger_account.objects.filter(company=request.user.current_company))

class lineFilter(filters.FilterSet):
    legder_account = filters.ModelChoiceFilter(queryset= accounts)

# usage
my_filter = transactionFilter(self.request.GET, queryset=transactions, request=self.request)

仅供参考,根据 PEP-8 style guide,类名应为 CamelCase,方法名应为 snake_case