如何根据 request.user 限制 Django 过滤器的选择
How to limit choices on the Django filter based on the request.user
我有一个多公司设置。用户登录到特定公司。每家公司都有自己的一套分类账户和交易。在交易清单上,我创建了过滤器选项,以便用户可以根据“描述”、“交易日期”和“分类帐帐户”进行过滤。分类账户的问题在于可用的选择是所有公司的账户。我想将选择限制为仅显示用户登录的当前公司的分类帐。
用户模型:
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 作为外键。
总账账户模型:
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
您可以这样尝试(基于 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.
,class 名称应为 CamelCase
,方法名称应为 snake_case
我有一个多公司设置。用户登录到特定公司。每家公司都有自己的一套分类账户和交易。在交易清单上,我创建了过滤器选项,以便用户可以根据“描述”、“交易日期”和“分类帐帐户”进行过滤。分类账户的问题在于可用的选择是所有公司的账户。我想将选择限制为仅显示用户登录的当前公司的分类帐。
用户模型:
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 作为外键。
总账账户模型:
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
您可以这样尝试(基于 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.
,class 名称应为CamelCase
,方法名称应为 snake_case