Django problem with request.get to postgresql - python

Getting stuck with this issue, I've got a table that has date, category and sum and I'm trying to make a query that can choose between dates to get records, but when i pick dates it screams "column "2020-12-12" does not exist"
views.py
def outgoings_history(request):
if request.method == "POST":
date_from= request.POST.get('date_from')
date_to= request.POST.get('date_to')
search_result = Outgoings.objects.filter(user=request.user).order_by('-date')\
.raw('SELECT suma, kategoria, date FROM outgoings WHERE date BETWEEN "2020-12-12" AND "2020-12-12"')
return render(request, 'outgoings_history.html', {'data': search_result})
else:
displaydata = Outgoings.objects.filter(user=request.user).order_by('-date')
return render(request, 'outgoings_history.html', {'data': displaydata})
forms.py
class PickADate(forms.Form):
date_from= forms.DateField(widget=DateInput())
date_to= forms.DateField(widget=DateInput())[enter image description here][1]
The date '2020-12-12' is just a example and it has records this day but still doesn't show anything

You don't need to use .raw for this, you can use a `.filter():
from django.contrib.auth.decorators import login_required
#login_required
def outgoings_history(request):
search_result = Outgoings.objects.filter(
user=request.user,
).order_by('-date')
if request.method == 'POST':
form = PickADate(request.POST)
if form.is_valid():
date_from = form.cleaned_data['date_from']
date_to = form.cleaned_data['date_to']
search_result = search_results.filter(
date__range=(date_from, date_to)
)
return render(request, 'outgoings_history.html', {'data': search_result})
Note: You can limit views to a view to authenticated users with the
#login_required decorator [Django-doc].

Related

NOT NULL constraint failed: mainsite_customer.user_id

I just wanna get profile with full form or empty form.
def local_cabinet(request):
user_id = request.user.id
caruser = Checkout.objects.filter(user=request.user)
# form = CheckoutForms()
orders = request.user.orderitem_set.all()
total_orders = orders.count()
ready_order = request.user.order_set.all()
customer = Customer.objects.filter(user=request.user)
customer_form = CustomerForm()
Maybe here's problem I don't know:
if request.method == 'POST':
if customer.exists():
form = CustomerForm(request.POST, request.FILES, instance=customer)
else:
form = CustomerForm(request.POST)
if form.is_valid():
form.save()
context = {
'caruser': caruser,
'orders': orders,
'total_orders': total_orders,
'ready_order': ready_order,
'cat_selected': 0,
'customer_form': customer_form,
'customer': customer,
}
return render(request, 'localcabinet.html', context=context)
I don't know why I get this, maybe because I'm not right at saving the form.
You are missing User instance in form, that you probably need to pass it after form creation and before saving it.
You didn't provide model nor forms, but I guess it will look like this:
if request.method == 'POST':
...
else:
form = CustomerForm(request.POST)
form.user = request.user
if form.is_valid():
form.save()
...
Another thing is that you assign queryset instead of single object with filter method:
customer = Customer.objects.filter(user=request.user) # gives queryset with probably one object
customer = Customer.objects.get(user=request.user) # gives an object - but gives Error if there is None or more than one
Probably the best approach to get single object is with try and except:
try:
customer = Customer.objects.get(user=request.user)
except Customer.DoesNotExists:
customer = None
then later instead of if customer.exists() you can use simple if customer.

How Can I sum the Result of a Django Date Range Result in Views

I want to add all the amount field during a date range query search. I have an Income Model with date and amount fields among others. And any time a user select between two dates, I want the amount fields of the query results added as total.
Here is what I have tried:
def SearchIncomeRange(request):
listIncome = Income.objects.all()
searchForm = IncomeSearchForm(request.POST or None)
if request.method == 'POST':
listIncome = Income.objects.filter(
description__icontains=searchForm['description'].value(),
date__range=[
searchForm['start_date'].value(),
searchForm['end_date'].value()
]
)
else:
searchForm = IncomeSearchForm()
paginator = Paginator(listIncome, 5)
page = request.GET.get('page')
paged_income = paginator.get_page(page)
context = {
'searchForm':searchForm,
}
return render(request, 'cashier/search_income_range.html', context)
I am able to get the correct search result but getting the total I don't know how to use the SUM in the above query and pass the total in pagination. So Someone should please help me out. Thanks
from django.db.models import Sum
total_amount = listIncome.aggregate(total=Sum('amount'))
where listIncome is your queryset
Edit:
You should pass queryset in pagination with filtered queryset if any filter you apply.
I changed your written code but you can write this code in a good way.
def SearchIncomeRange(request):
listIncome = Income.objects.all()
searchForm = IncomeSearchForm(request.POST or None)
if request.method == 'POST':
# you can get filter value by your form data
post_data = request.POST
description = post_data['description']
start_date = post_data['start_date']
end_date = post_data['end_date']
else:
# you can get filter value by your query params
query_params = request.GET
description = query_params.get('description')
start_date = query_params.get('start_date')
end_date = query_params.get('end_date')
# Apply filter before pagination
listIncome = listIncome.filter(
description__icontains=description,
date__range=[start_date, end_date]
)
# calculate total_amount
total_amount = listIncome.aggregate(total=Sum('amount'))
paginator = Paginator(listIncome, 5)
page = request.GET.get('page')
paged_income = paginator.get_page(page)
# you can access total_amount in template by passing in context data
context = {
'searchForm':searchForm,
'total_amount': total_amount
}
return render(request, 'cashier/search_income_range.html', context)

How do I redirect to url2 after performing a task on url1 in django?

I have a edit-scholarship.html in which you can search for a scholarship by passing name and type and then select that scholarship and edit it in update-scholarship.html by passing scholarship id from the url.
Now after updating the scholarship, the url becomes
http://127.0.0.1:8000/admin/updatescholarship/50
50 is the scholarship id passed into the url
Now when I try to go to dashboard in my project, the url becomes
http://127.0.0.1:8000/admin/updatescholarship/dashboard
I dont't want the dashboard to get appended after the updatescholarship . The url should be
http://127.0.0.1:8000/admin/dashboard
Here's my edit-scholarship view
def admin_editscholarship(request):
if request.method == 'POST':
name = request.POST['sch_name']
type = request.POST['sch_type']
schdets = ScholarshipDetails.objects.filter(name = name,type = type)
if schdets is not None:
#if something exists in scholarship details, then print it
print('Scholarship found')
else:
schdets = None
return render(request,'admin-editscholarship.html',{'schdets':schdets})
Here's my update-scholarship view
def admin_updatescholarship(request,pk=None):
#can update the new data in the selectd scholarship
if pk:
sch = ScholarshipDetails.objects.get(pk = pk)
if request.method == 'POST':
form = EditScholarshipForm(request.POST,instance=sch)
if form.is_valid():
form.save()
print('\nform saved')
args = {'form' : form}
messages.success(request,'Successfully updated')
return render(request,'admin-editscholarship.html',args)
Here's my urls.py
path('admin/dashboard',views.admin_dash),
path('admin/addscholarship',views.admin_addscholarship),
path('admin/editscholarship',views.admin_editscholarship),
url(r'^admin/updatescholarship/(?P<pk>\d+)$',views.admin_updatescholarship,name =
'updatescholarship'),
path('admin/students',views.admin_students),
path('admin/requests',views.admin_requests)
you can redirect to other url using django redirect
from django.shortcuts import redirect
def fn_test(request):
task here
return redirect('path_to_redirect/')

2 forms, 1 view, 2 SQL tables in Django

I'm struggling to understand how to submit data from two django forms into two separate database tables from the same view. I only want one submit button. While this question got me closer to the solution, I'm getting errors and the data is not writing to the database. I think this code actually checks the two forms against each other instead of submitting both forms in one go. Any ideas?
Here's what I've tried:
For one form --> one table. This works, so it's a start.
# views.py
def BookFormView(request):
if request.method == 'POST':
form = BookForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect("/books/")
else:
form = BookForm()
return render(request, 'books/createbooks.html',
{'form' : form})
However, when I add this form in from forms.py to get the subsequent views.py I get local variable 'book_form' referenced before assignment. That's usually an easy global-vs-local variable issue to fix, but I don't know what it means in this case.
def BookFormView(request):
if request.method == 'POST':
if 'book' in request.POST:
book_form = BookForm(request.POST, prefix='book')
if book_form.is_valid():
book_form.save()
return HttpResponseRedirect("/books/")
bookdetailsform = BookDetailsForm(prefix='bookdetails')
elif 'bookdetails' in request.POST:
bookdetailsform = BookDetailsForm(request.POST, prefix='bookdetails')
if bookdetailsform.is_valid():
bookdetailsform.save()
return HttpResponseRedirect("/books/")
book_form = BookForm(prefix='book')
else:
book_form = BookForm(prefix='book')
bookdetailsform = BookDetailsForm(prefix='bookdetails')
return render(request, 'books/createbook.html',
{'book_form' : book_form,
'bookdetailsform': bookdetailsform})
Based on the question's comments:
def BookFormView(request):
if request.method == 'POST':
book_form = BookForm(request.POST, prefix='book')
bookdetailsform = BookDetailsForm(request.POST, prefix='bookdetails')
if book_form.is_valid() and bookdetailsform.is_valid():
book_form.save()
bookdetailsform.save()
return HttpResponseRedirect("/books/")
else:
book_form = BookForm(prefix='book')
bookdetailsform = BookDetailsForm(prefix='bookdetails')
return render(request, 'books/createbook.html',
{'book_form': book_form, 'bookdetailsform': bookdetailsform})
I think the problem is that when a user submits a bookdetails post request,
it will be handled under if 'book' in request.POST: condition. Why?
because string bookdetails contains string book, no matter the type of request they do, it will be handled with if book in request.POST: condition.
I believe fixing that if condition problem is the first step.

Filtering data with __range

I'm using django_tables2 thus part of the code is dependent on this package, but this should be irrelevant to the overall problem.
forms.py
class PersonForm(forms.Form):
date_from = forms.DateField(input_formats='%d/%m/%Y')
date_to = forms.DateField(input_formats='%d/%m/%Y')
views.py
def filter(request):
table = PersonTable(Person.objects.all())
if request.method == 'POST':
form = PersonForm(request.POST)
if form.is_valid():
date_from = form.cleaned_data['date_from']
date_to = form.cleaned_data['date_to']
result_filtered = table.filter(date__range=(date_from, date_to))
RequestConfig(request, paginate={"per_page": 100}).configure(table)
return render(request, "people.html", {
"table": result_filtered })
args = {}
args.update(csrf(request))
args['form'] = PersonForm()
args['table'] = table
RequestConfig(request, paginate={"per_page": 100}).configure(table)
return render(request, 'people.html', args)
Simply, filtering is not working. I can see the entire table, but when I try to filter nothing happens. Can you see what's wrong?
I'm pretty sure you need to call .filter() on the query set rather than the table. For example:
result_filtered = PersonTable(Person.objects.filter(date__range=(date_from, date_to))
Also, on this line:
RequestConfig(request, paginate={"per_page": 100}).configure(table)
You are passing in table. You should pass in result_filtered instead.
This is one way I'd do it, assuming your Person model has a date field:
def filter(request):
if 'date_from' in request.GET and 'date_to' in request.GET:
# form data has been submitted
form = PersonForm(request.GET)
if form.is_valid():
date_from = form.cleaned_data['date_from']
date_to = form.cleaned_data['date_to']
people = Person.objects.filter(date__range=(date_from, date_to))
table = PersonTable(people)
else:
table = PersonTable(Person.objects.all())
else:
form = PersonForm()
table = PersonTable(Person.objects.all())
RequestConfig(request, paginate={"per_page": 100}).configure(table)
args = {}
args.update(csrf(request))
args['form'] = form
args['table'] = table
return render(request, 'people.html', args)
This binds the form if both its expected fields are present, and limits the queryset according to the results if valid. If not valid, it renders the bound form and the table built from the unlimited table. If form data was not submitted, it renders the table built from the unlimited table.
Your form tag's method attribute should be GET rather than POST, if using this design.
This doesn't quite follow the usual Django patterns for form handling because the form isn't actually making any changes, so you can use GET and don't need to return a redirect on success.

Categories

Resources