I want pagination of following UserListView
class UserListView(LoginRequiredMixin, generic.TemplateView):
template_name = 'users/users.html'
paginate_by = 1
def get_context_data(self, **kwargs):
context = super(UserListView, self).get_context_data(**kwargs)
context['companies'] = Company.objects.exclude(company_is_deleted=True).exclude(company_name='Apollo')
context['users'] = User.objects.filter(userprofile__user_role__id=2).exclude(
Q(is_superuser=True) |
Q(userprofile__user_is_deleted = True)|
Q(userprofile__user_company__company_is_deleted=True)
)
query = self.request.GET.get('query')
if query:
list_query = context['users']
context['users'] = list_query.filter(userprofile__user_company__company_name__icontains=query)
return context
class UserListView(LoginRequiredMixin, generic.ListView):
template_name = 'users/users.html'
paginate_by = 1
context_object_name = 'users'
def get_queryset(self, *args, **kwargs):
qs = User.objects.filter(userprofile__user_role__id=2).exclude(
Q(is_superuser=True) |
Q(userprofile__user_is_deleted = True)|
Q(userprofile__user_company__company_is_deleted=True)
)
query = self.request.GET.get('query')
if query:
qs = qs.filter(userprofile__user_company__company_name__icontains=query)
return qs
def get_context_data(self, **kwargs):
context = super(UserListView, self).get_context_data(**kwargs)
context['companies'] = Company.objects.exclude(company_is_deleted=True).exclude(company_name='Apollo')
return context
If you need custom pagination you should take a look at the docs
Related
I use a CB ListView for displaying objects. I want to add a session variable based on another models' PK during the execution of my ListView:
views.py
class ProduitListView(LoginRequiredMixin, ListView):
model = Produit
context_object_name = "produits"
paginate_by = 10
template_name = 'products/produits.html'
ordering = ['-mageid', ]
def get_context_data(self, *args, **kwargs):
context = super(ProduitListView, self).get_context_data(
*args, **kwargs)
# used for incoming products (sourcing cf URLS)
supplier_pk = self.kwargs.get('pk', None)
if supplier_pk:
set_incoming_supplier(self.request, supplier_pk)
context['avail_warehouses'] = Warehouse.objects.all()
context['js_warehouses'] = serialize(
'json', Warehouse.objects.all(), fields=('code', 'id', ))
context['title'] = 'Produits'
return context
set_incoming_supplier (in another APP)
#login_required
def set_incoming_supplier(request, pk):
supplier = Supplier.objects.filter(pk=pk).first()
supp = SupplierSerializer(instance=supplier).data
rs = request.session
if 'income' in rs:
if 'cur_supplier' in rs['income']:
prev_supplier = rs['income']['cur_supplier']
if supp != prev_supplier:
return render(request, 'sourcing/alert_supplier_change.html',
{'prev_supplier': prev_supplier, 'cur_supplier': rs['income']['cur_supplier']})
rs['income'] = {'cur_supplier': supp}
I thought the return render(request, 'sourcing/alert_supplier_change... could "break" my ListView and render my alert page but it doesn't. ListView seems to continue and finally renders my ProduitListView page.
Why doesn't this work ?
Finally found a solution that consists in using get() method within my CBV. In it, I evaluate my supplier with set_incoming_supplier() that returns a context or None. According to this evaluation, I render either the regular template or my alert template.
ProduitListView(LoginRequiredMixin, ListView):
class ProduitListView(LoginRequiredMixin, ListView):
model = Produit
context_object_name = "produits"
paginate_by = 10
template_name = 'products/produits.html'
ordering = ['-mageid', ]
def get_context_data(self, *args, **kwargs):
context = super(ProduitListView, self).get_context_data(
*args, **kwargs)
context['avail_warehouses'] = Warehouse.objects.all()
context['js_warehouses'] = serialize(
'json', Warehouse.objects.all(), fields=('code', 'id', ))
context['title'] = 'Produits'
return context
def get(self, request, *args, **kwargs):
supplier_pk = self.kwargs.get('pk', None)
if supplier_pk:
context = set_incoming_supplier(self.request, supplier_pk)
if context:
return render(request, 'sourcing/alert_supplier_change.html', context)
return super().get(request, *args, **kwargs)
set_incoming_supplier()
def set_incoming_supplier(request, pk):
supplier = Supplier.objects.filter(pk=pk).first()
supp = SupplierSerializer(instance=supplier).data
rs = request.session
if 'income' in rs:
if 'cur_supplier' in rs['income']:
prev_supplier = rs['income']['cur_supplier']
if supp != prev_supplier:
return {'prev_supplier': prev_supplier, 'cur_supplier': supp}
rs['income'] = {'cur_supplier': supp}
Maybe not the best way but it works well.
I have implemented two views to display data according to the choice_fields but i have two views with slightly different logic in views and templates how do i combine them into one so that i take care of DRY
views.py:
class View1(LoginRequiredMixin,TemplateView):
template_name = 'temp1.html'
def get_context_data(self, **kwargs):
context = super(View1,self).get_context_data(**kwargs)
context['progress'] = self.kwargs.get('progress', 'in_progress')
if context['progress'] == 'in_progress':
context['objects'] = Model.objects.filter(progress='in_progress')
else:
context['objects'] = Model.objects.filter(progress__iexact=context['progress'], accepted=self.request.user)
return context
class View2(LoginRequiredMixin,TemplateView):
template_name = 'temp2.html'
def get_context_data(self, **kwargs):
context = super(View2,self).get_context_data(**kwargs)
context['progress'] = self.kwargs.get('progress', 'in_progress')
if context['progress'] == 'in_progress':
context['objects'] = Model.objects.filter(progress='in_progress',created = self.request.user)
else:
context['objects'] = Model.objects.filter(progress__iexact=context['progress'], created_by=self.request.user)
return context
Implement something like get_queryset in Class-based views.
class BaseView(LoginRequiredMixin,TemplateView):
""" requires subclassing to define template_name and
update_qs( qs, progress) method """
def get_context_data(self, **kwargs):
context = super(View1,self).get_context_data(**kwargs)
progress = self.kwargs.get('progress', 'in_progress')
if progress == 'in_progress':
qs = Model.objects.filter(progress='in_progress')
else:
qs = Model.objects.filter(progress__iexact=context['progress'] )
qs = self.update_qs( qs, (progress == 'in_progress') )
context['progress'] = progress
context['objects'] = qs
return context
class View1( BaseView):
template_name = 'temp1.html'
def update_qs( self, qs, in_progress):
if in_progress:
return qs
else:
return qs.filter( accepted=self.request.user)
class View2( BaseView):
template_name = 'temp2.html'
def update_qs( self, qs, in_progress):
if in_progress:
return qs.filter( created = self.request.user)
else:
return qs.filter( created_by=self.request.user)
i want that a form is prepoluate with data
my model:
TYPE = (("S",'Swing'),
("R","Rapide"))
class valuation(models.Model):
stock = models.ForeignKey("stock",on_delete=models.CASCADE,related_name='valuation',)
date = models.DateField(auto_created=True)
val_type = models.CharField(choices=TYPE, max_length=1,default='R')
user = models.ForeignKey("users.User", on_delete=models.CASCADE)
def __str__(self):
return f"{self.stock} - {self.date} - {self.val_type}"
my view:
class valuationCreateviewSwing(CreateView):
template_name = "evaluation/evaluation_create.html"
form_class = valuationModeform
def get_form_kwargs(self): # prepopulate form
kwargs = super(valuationCreateviewSwing, self).get_form_kwargs()
stck = get_object_or_404(stock, pk=self.kwargs['pk'])
kwargs['user'] = self.request.user
kwargs['val_type'] = "S"
kwargs['stock'] = stck
return kwargs
def get_context_data(self, **kwargs):
# we need to overwrite get_context_data
# to make sure that our formset is rendered
data = super().get_context_data(**kwargs)
if self.request.POST:
data["val_detail"] = ChildFormset1(self.request.POST)
else:
data["val_detail"] = ChildFormset1()
data.update({
"typeVal": "Swing",})
return data
def form_valid(self, form):
context = self.get_context_data()
val_detail_Swing = context["val_detail_Swing"]
self.object = form.save(commit=False)
# add data info neede about valuation model
self.object = form.save()
if val_detail_Swing.is_valid():
val_detail_Swing.instance = self.object
val_detail_Swing.save()
return super().form_valid(form)
def get_success_url(self):
return reverse("stock:stock-list")
I've a child form in my view (this part works ok):
ChildFormset1 = inlineformset_factory(
valuation, val_detail_Swing, form=valuationSwingModelform, can_delete=False)
I tried to use ge_for_kwargs but it seems not working as I've an error message :
init() got an unexpected keyword argument 'user'
You can use get_initial() method:
class valuationCreateviewSwing(CreateView):
template_name = "evaluation/evaluation_create.html"
form_class = valuationModeform
def get_initial(self):
query = self.request.GET
return {
'user': self.request.user.pk
'val_type': "S",
'stock': self.kwargs.get('pk')
}
...
Or you should override __init__() method and stay to use get_form_kwargs()
class valuationModeform(ModelForm):
class Meta:
model = Valuation
fields = '__all__'
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
val_type = kwargs('val_type', None)
stock = kwargs.pop('stock', None)
super().__init__(*args, **kwargs)
# assign initial values
self.fields['user'].initial = user
self.fields['val_type'].initial = val_type
self.fields['stock'].initial = stock
I have these models:
class Purchase(models.Model):
company = models.ForeignKey(Company,on_delete=models.CASCADE,null=True,blank=True)
party_ac = models.ForeignKey(Ledger1,on_delete=models.CASCADE,related_name='partyledger')
purchase = models.ForeignKey(Ledger1,on_delete=models.CASCADE,related_name='purchaseledger')
total = models.DecimalField(max_digits=10,decimal_places=2,null=True,blank=True)
class Stock_total(models.Model):
company = models.ForeignKey(Company,on_delete=models.CASCADE,null=True,blank=True)
purchases = models.ForeignKey(Purchase,on_delete=models.CASCADE,null=True,blank=False,related_name='purchasetotal')
stockitem = models.ForeignKey(Stockdata,on_delete=models.CASCADE,null=True,blank=True,related_name='purchasestock')
total = models.DecimalField(max_digits=10,decimal_places=2,default=0.00,null=True,blank=True)
This are my forms:
class Purchase_form(forms.ModelForm):
class Meta:
model = Purchase
fields = ('Company','Party_ac', 'purchase', 'sub_total')
def __init__(self, *args, **kwargs):
self.User = kwargs.pop('User', None)
self.Company = kwargs.pop('Company', None)
super(Purchase_form, self).__init__(*args, **kwargs)
self.fields['party_ac'].queryset = Ledger1.objects.filter(Q(Company = self.Company) , Q(group1_Name__group_Name__icontains='Sundry Creditors') | Q(group1_Name__group_Name__icontains='Bank Accounts') | Q(group1_Name__group_Name__icontains='Cash-in-hand') | Q(group1_Name__Master__group_Name__icontains='Sundry Creditors') | Q(group1_Name__Master__group_Name__icontains='Bank Accounts') | Q(group1_Name__Master__group_Name__icontains='Cash-in-hand'))
self.fields['party_ac'].widget.attrs = {'class': 'select2_demo_2 form-control',}
self.fields['purchase'].queryset = Ledger1.objects.filter(Q(Company = self.Company) ,Q(group1_Name__group_Name__icontains='Purchase Accounts') | Q(group1_Name__Master__group_Name__icontains='Purchase Accounts'))
self.fields['purchase'].widget.attrs = {'class': 'select2_demo_2 form-control',}
self.fields['total'].widget.attrs = {'class': 'form-control',}
class Stock_Totalform(forms.ModelForm):
class Meta:
model = Stock_Total
fields = ('stockitem', 'Total_p')
def __init__(self, *args, **kwargs):
super(Stock_Totalform, self).__init__(*args, **kwargs)
self.fields['stockitem'].widget.attrs = {'class': 'select2_demo_2 form-control',}
self.fields['total'].widget.attrs = {'class': 'form-control',}
Purchase_formSet = inlineformset_factory(Purchase, Stock_Total,
form=Stock_Totalform, extra=3)
The views:
class Purchase_createview(ProductExistsRequiredMixin,Company_only_accounts_mixins,LoginRequiredMixin,CreateView):
form_class = Purchase_form
template_name = 'stockkeeping/purchase/purchase_form.html'
def get_context_data(self, **kwargs):
context = super(Purchase_createview, self).get_context_data(**kwargs)
company_details = get_object_or_404(Company, pk=self.kwargs['pk'])
context['company_details'] = company_details
selectdatefield_details = get_object_or_404(Selectdatefield, pk=self.kwargs['pk3'])
context['selectdatefield_details'] = selectdatefield_details
if self.request.POST:
context['stocks'] = Purchase_formSet(self.request.POST)
else:
context['stocks'] = Purchase_formSet()
return context
def form_valid(self, form):
c = Company.objects.get(pk=self.kwargs['pk'])
form.instance.Company = c
context = self.get_context_data()
stocks = context['stocks']
with transaction.atomic():
self.object = form.save()
if stocks.is_valid():
stocks.instance = self.object
stocks.save()
return super(Purchase_createview, self).form_valid(form)
def get_form_kwargs(self):
data = super(Purchase_createview, self).get_form_kwargs()
data.update(
Company=Company.objects.get(pk=self.kwargs['pk'])
)
return data
I want to perform a queryset method for stockitem field in Stock_Totalform which I will make specific to Company like I have done for Party_ac and purchase in Purchase_form above..
When I try to do the same for Stock_Totalform objects it gives me no result..
I tried like above doing: self.Company = kwargs.pop('Company', None) using the get_form_kwargs function in views.
But it looks like it doesnot works for the ForeignKey field which is inlined with a parent model.
Can anyone help to to solve this issue.
Thank you
These are my forms:
class MultijournaltotalForm(forms.ModelForm):
class Meta:
model = Multijournaltotal
fields = ('Date', 'Total_Debit', 'Total_Credit')
widgets = {
'Date': DateInput(),
}
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('User', None)
self.company = kwargs.pop('Company', None)
super(MultijournaltotalForm, self).__init__(*args, **kwargs)
self.fields['Date'].widget.attrs = {'class': 'form-control',}
self.fields['Total_Debit'].widget.attrs = {'class': 'form-control',}
self.fields['Total_Credit'].widget.attrs = {'class': 'form-control',}
class MultijournalForm(forms.ModelForm):
class Meta:
model = Multijournal
fields = ('By','To','Debit','Credit','narration')
def __init__(self, *args, **kwargs):
self.User = kwargs.pop('User', None)
self.Company = kwargs.pop('Company', None)
super(MultijournalForm, self).__init__(*args, **kwargs)
self.fields['Debit'].widget.attrs = {'class': 'form-control',}
self.fields['Credit'].widget.attrs = {'class': 'form-control',}
self.fields['To'].widget.attrs = {'class': 'form-control select2',}
self.fields['By'].widget.attrs = {'class': 'form-control select2',}
self.fields['narration'].widget.attrs = {'class': 'form-control',}
Multijournal_formSet = inlineformset_factory(
Multijournaltotal,
Multijournal,
form=MultijournalForm,
extra=6,
)
I am facing a problem in updating my inline formset from quite a long time. The create view works perfectly fine but when I try to update the instances of Multijournal in Multijournaltotal then the objects are not shown in the formset...
I tried this previously:
class Multijournal_updateview(LoginRequiredMixin,UpdateView):
model = Multijournaltotal
form_class = MultijournaltotalForm
template_name = 'Multijournal/multi_journal_form.html'
def get_success_url(self,**kwargs):
company_details = get_object_or_404(Company, pk=self.kwargs['pk'])
multijournal_details = get_object_or_404(Multijournaltotal, pk=pk2)
selectdatefield_details = get_object_or_404(Selectdatefield, pk=self.kwargs['pk3'])
return reverse(
'accounting_double_entry:multijournaldetail',
kwargs={
'pk1':company_details.pk,
'pk2':multijournal_details.pk,
'pk3':selectdatefield_details.pk
},
)
def get_context_data(self, **kwargs):
context = super(Multijournal_updateview, self).get_context_data(**kwargs)
company_details = get_object_or_404(Company, pk=self.kwargs['pk'])
context['company_details'] = company_details
selectdatefield_details = get_object_or_404(Selectdatefield, pk=self.kwargs['pk3'])
context['selectdatefield_details'] = selectdatefield_details
multijournal_details = get_object_or_404(Multijournaltotal, pk=self.kwargs['pk2'])
queryset = Multijournal.objects.filter(total= multijournal_details.id)
multijournalformset = Multijournal_formSet(self.request.POST or None, queryset=queryset)
context['multijournalformset'] = multijournalformset
return context
Can anyone tell me if I am going in right direction?
Thank you