I have a multi company setup. The user is logged into to a specific company. Every company has its own set of ledger accounts and transactions. On the transaction list I created filter options so that the user can filter based on "Description", "Transaction date" and "Ledger account". The problem with the Ledger Account is that the choices available is the accounts from all the companies. I ant to limit the choices to only show the Ledger Accounts from the current company that the user is logged into.
User model:
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)
Note the current_company as a ForeignKey.
Leger Account Model:
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']
Note the company as a ForeignKey.
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']
This setup gives me an error: "name 'request' is not defined"
The question is how do I get the request.user to the filter.py
You can try like this(based on example from 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)
FYI, class names should be CamelCase
and method names should be snake_case
as per PEP-8 style guide.