django admin - custom action template - python

Im trying to add a custom action to django app, where i can redirect to a html (pdf) page i created.
currently the html page only shows 1 result, What im trying to do is to show as many as objects i selcet from the action bar in django admin. here is my code.. admin.py
def print_pdf(modelAdmin, request, queryset, **kwargs):
from django.template.loader import get_template
from django.http import HttpResponse
from django.shortcuts import render, get_object_or_404
from calculator.models import Transaction
from xhtml2pdf import pisa
chp = []
for f in queryset:
chp.append(f.chp_reference)
for q in range(len(queryset)): # here im trying to know how many times to iterate based on how many qs selected
transaction = get_object_or_404(Transaction, chp_reference=chp[1]) #im not sure what to do here
template_path = 'report-pdf.html'
context = {"transactions":transactions}
response = HttpResponse(content_type='Application/pdf')
response['Content-Disposition'] = 'filename="report.pdf'
template = get_template(template_path)
html = template.render(context)
pisa_status = pisa.CreatePDF(html, dest=response)
if pisa_status.err:
return HttpResponse('we had some errors' + html )
return response
print_pdf.short_description = 'bulk pdf'
actions = [export_csv, print_pdf]
here is my code. I know its messed up, but i been trying to figure out to do this but im lost.
help would be appreciated

What's happening is the difference between the following snipppets.
def f(x)
for i in range(x):
return i ** 2
f(5) # 0 ONLY
def f(x):
results = []
for i in range(x):
results.append(i ** 2)
return results
You're returning after the first iteration, so the loop finishes after the first iteration.
You need to do the same as the second one, collect all results and return them at the end.
To illustrate what you want, this is based on your reply here. You can use something like
transactions = Transaction.objects.none()
for pk in chp:
qs = Transaction.objects.filter(chp_reference=i)
transactions = transaction.union(qs)
return transactions
and improve it based on your needs

Related

Django Redirect does not work at all within view

I am trying to get my view to redirect to another page after clicking a button that triggers the POST request. I cannot seem to figure out why the redirect doesn't work or why it doesn't even seem to try to redirect.
Here is my view:
def cart1(request):
if request.user.is_authenticated:
#POST
if request.method == "POST":
#JSON Data
data = request.body
new_data = ast.literal_eval(data.decode('utf-8'))
customer = request.user
user_order = Order(user=customer)
user_order.save()
x = 0
while x < len(new_data.keys()):
obj_title = new_data[x]["title"]
obj_price = new_data[x]["price"]
obj_quantity = new_data[x]["quantity"]
obj_extra = new_data[x]["extra"]
total = round(float(obj_price.replace("$", "")))
m = OrderItem(order=user_order, title=obj_title, price=total, quantity=obj_quantity, extra=obj_extra)
m.save()
x += 1
return redirect('checkout-page')
return render(request, 'cart.html')
Any help would be appreciated, thank you
redirect(…) [Django-doc] produces a HttpRedirectResponse, you need to return it, so:
return redirect('checkout-page')
redirect(…) itself thus does not stop the code flow to redirect return a HTTP redirect response, it constructs such response, and your view should then return that response.
you need to be sure the URL name =checkout-page is in the current app otherwise you need to make it redirect('app:checkout-page')
However,I suggest to use from django.http import HttpResponseRedirect

Can I use the values from a form in other form with Django?

I have a Django app with two forms where the views.py looks like this:
import pandas as pd
import numpy as np
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from django.template.response import TemplateResponse
from pbmcalculator.models import PbmCalculator, simulator
from django.core.cache import cache
import json
#login_required
def subs_calc(request):
# this is from the first form #
selection = request.GET.get("id", None)
customer = request.GET.get("customer", None)
initial_date = request.GET.get("initial_date", None)
final_date = request.GET.get("final_date", None)
if selection is not None and 'initial_date' in request.GET:
calculation_target = PbmCalculator(customer, initial_date, final_date)
html = TemplateResponse(
request,
"pbmcalculator/table.html",
{
some operations
},
)
return html
if 'generico_sim' in request.GET:
# this is from the second form #
brand_sim = request.GET.get("brand_sim",None)
generico_sim = request.GET.get("generico_sim",None)
marca_sim = request.GET.get("marca_sim",None)
initial_date_sim = '2021-08-08'
final_date_sim = '2021-08-15'
calculation_sim = simulator(brand_sim, initial_date_sim, final_date_sim)
html = TemplateResponse(
request,
"pbmcalculator/table1.html",
{
some operations
},
)
return html
return render(request, "pbmcalculator/subs_calc.html", {"selected": False})
So I want to use the variables initial_date and final_date in the second if statement to fill the initial_date_sim and final_date_sim. I tried several ways but none worked. Some idea?
I solved this issue by taking the values through the ajax of each form, there it doesn't matter if the value comes from one or the other. then the second form will be filtered by the dates of the first as I wanted. Thank you Jelle for your time.

How to render output of cartridge API's on custom HTML page?

I am working on a cartridge project. I have created custom html templates for better visual and now I want to render all data which is coming through cartridge's built in APIs on my custom html pages. For.ex. I have a product.html, on which I want to show all products stored in db (category wise).
Actually, I tried to explore url,
url("^shop/", include("cartridge.shop.urls")),
I am not getting that on which API or Function, this url is hitting.
urls.py file of shop app looks like this, I tested it, none of those url get called,
from __future__ import unicode_literals
from django.conf.urls import url
from mezzanine.conf import settings
from cartridge.shop import views
_slash = "/" if settings.APPEND_SLASH else ""
urlpatterns = [
url("^product/(?P<slug>.*)%s$" % _slash, views.product,
name="shop_product"),
url("^wishlist%s$" % _slash, views.wishlist, name="shop_wishlist"),
url("^cart%s$" % _slash, views.cart, name="shop_cart"),
url("^checkout%s$" % _slash, views.checkout_steps, name="shop_checkout"),
url("^checkout/complete%s$" % _slash, views.complete,
name="shop_complete"),
url("^invoice/(?P<order_id>\d+)%s$" % _slash, views.invoice,
name="shop_invoice"),
url("^invoice/(?P<order_id>\d+)/resend%s$" % _slash,
views.invoice_resend_email, name="shop_invoice_resend"),
]
These are cartridge's views for '/shop/product', '/shop/wishlist' and '/shop/cart'
from __future__ import unicode_literals
from future.builtins import int, str
from json import dumps
from django.contrib.auth.decorators import login_required
from django.contrib.messages import info
from django.core.urlresolvers import reverse
from django.db.models import Sum
from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404, redirect
from django.template import RequestContext
from django.template.defaultfilters import slugify
from django.template.loader import get_template
from django.template.response import TemplateResponse
from django.utils.translation import ugettext as _
from django.views.decorators.cache import never_cache
from mezzanine.conf import settings
from mezzanine.utils.importing import import_dotted_path
from mezzanine.utils.views import set_cookie, paginate
from mezzanine.utils.urls import next_url
from cartridge.shop import checkout
from cartridge.shop.forms import (AddProductForm, CartItemFormSet,
DiscountForm, OrderForm)
from cartridge.shop.models import Product, ProductVariation, Order
from cartridge.shop.models import DiscountCode
from cartridge.shop.utils import recalculate_cart, sign
try:
from xhtml2pdf import pisa
except (ImportError, SyntaxError):
pisa = None
HAS_PDF = pisa is not None
# Set up checkout handlers.
handler = lambda s: import_dotted_path(s) if s else lambda *args: None
billship_handler = handler(settings.SHOP_HANDLER_BILLING_SHIPPING)
tax_handler = handler(settings.SHOP_HANDLER_TAX)
payment_handler = handler(settings.SHOP_HANDLER_PAYMENT)
order_handler = handler(settings.SHOP_HANDLER_ORDER)
def product(request, slug, template="shop/product.html",
form_class=AddProductForm, extra_context=None):
"""
Display a product - convert the product variations to JSON as well as
handling adding the product to either the cart or the wishlist.
"""
published_products = Product.objects.published(for_user=request.user)
product = get_object_or_404(published_products, slug=slug)
fields = [f.name for f in ProductVariation.option_fields()]
variations = product.variations.all()
variations_json = dumps([dict([(f, getattr(v, f))
for f in fields + ["sku", "image_id"]]) for v in variations])
to_cart = (request.method == "POST" and
request.POST.get("add_wishlist") is None)
initial_data = {}
if variations:
initial_data = dict([(f, getattr(variations[0], f)) for f in fields])
initial_data["quantity"] = 1
add_product_form = form_class(request.POST or None, product=product,
initial=initial_data, to_cart=to_cart)
if request.method == "POST":
if add_product_form.is_valid():
if to_cart:
quantity = add_product_form.cleaned_data["quantity"]
request.cart.add_item(add_product_form.variation, quantity)
recalculate_cart(request)
info(request, _("Item added to cart"))
return redirect("shop_cart")
else:
skus = request.wishlist
sku = add_product_form.variation.sku
if sku not in skus:
skus.append(sku)
info(request, _("Item added to wishlist"))
response = redirect("shop_wishlist")
set_cookie(response, "wishlist", ",".join(skus))
return response
related = []
if settings.SHOP_USE_RELATED_PRODUCTS:
related = product.related_products.published(for_user=request.user)
context = {
"product": product,
"editable_obj": product,
"images": product.images.all(),
"variations": variations,
"variations_json": variations_json,
"has_available_variations": any([v.has_price() for v in variations]),
"related_products": related,
"add_product_form": add_product_form
}
context.update(extra_context or {})
templates = [u"shop/%s.html" % str(product.slug), template]
return TemplateResponse(request, templates, context)
#never_cache
def wishlist(request, template="shop/wishlist.html",
form_class=AddProductForm, extra_context=None):
"""
Display the wishlist and handle removing items from the wishlist and
adding them to the cart.
"""
if not settings.SHOP_USE_WISHLIST:
raise Http404
skus = request.wishlist
error = None
if request.method == "POST":
to_cart = request.POST.get("add_cart")
add_product_form = form_class(request.POST or None,
to_cart=to_cart)
if to_cart:
if add_product_form.is_valid():
request.cart.add_item(add_product_form.variation, 1)
recalculate_cart(request)
message = _("Item added to cart")
url = "shop_cart"
else:
error = list(add_product_form.errors.values())[0]
else:
message = _("Item removed from wishlist")
url = "shop_wishlist"
sku = request.POST.get("sku")
if sku in skus:
skus.remove(sku)
if not error:
info(request, message)
response = redirect(url)
set_cookie(response, "wishlist", ",".join(skus))
return response
# Remove skus from the cookie that no longer exist.
published_products = Product.objects.published(for_user=request.user)
f = {"product__in": published_products, "sku__in": skus}
wishlist = ProductVariation.objects.filter(**f).select_related("product")
wishlist = sorted(wishlist, key=lambda v: skus.index(v.sku))
context = {"wishlist_items": wishlist, "error": error}
context.update(extra_context or {})
response = TemplateResponse(request, template, context)
if len(wishlist) < len(skus):
skus = [variation.sku for variation in wishlist]
set_cookie(response, "wishlist", ",".join(skus))
return response
#never_cache
def cart(request, template="shop/cart.html",
cart_formset_class=CartItemFormSet,
discount_form_class=DiscountForm,
extra_context=None):
"""
Display cart and handle removing items from the cart.
"""
cart_formset = cart_formset_class(instance=request.cart)
discount_form = discount_form_class(request, request.POST or None)
if request.method == "POST":
valid = True
if request.POST.get("update_cart"):
valid = request.cart.has_items()
if not valid:
# Session timed out.
info(request, _("Your cart has expired"))
else:
cart_formset = cart_formset_class(request.POST,
instance=request.cart)
valid = cart_formset.is_valid()
if valid:
cart_formset.save()
recalculate_cart(request)
info(request, _("Cart updated"))
else:
# Reset the cart formset so that the cart
# always indicates the correct quantities.
# The user is shown their invalid quantity
# via the error message, which we need to
# copy over to the new formset here.
errors = cart_formset._errors
cart_formset = cart_formset_class(instance=request.cart)
cart_formset._errors = errors
else:
valid = discount_form.is_valid()
if valid:
discount_form.set_discount()
# Potentially need to set shipping if a discount code
# was previously entered with free shipping, and then
# another was entered (replacing the old) without
# free shipping, *and* the user has already progressed
# to the final checkout step, which they'd go straight
# to when returning to checkout, bypassing billing and
# shipping details step where shipping is normally set.
recalculate_cart(request)
if valid:
return redirect("shop_cart")
context = {"cart_formset": cart_formset}
context.update(extra_context or {})
settings.use_editable()
if (settings.SHOP_DISCOUNT_FIELD_IN_CART and
DiscountCode.objects.active().exists()):
context["discount_form"] = discount_form
return TemplateResponse(request, template, context)
When you hit shop url, your application will try to use an empty url from your cartridge.shop.urls file. So basically when you would like to check which API / view is called, go to this file and look for something similar to this:
url(r'^$', 'your-view', name='your-view'),
ok after posting your second urls file you have following options:
you call:
/shop/wishlist/ - you are executing a view named wishlist
/shop/cart/ - you are executing a view named cart
/shop/checkout/complete/ - you are executing a view named complete
so just find your views.py file, and all those views are going to be there

Django calling a view from another view

So I have a view that displays some data based on the Person that is searched from the home page:
def film_chart_view(request):
if 'q' in request.GET and request.GET['q']:
q = request.GET['q']
# grab the first person on the list
try:
person_search = Person.objects.filter(short = q)[0]
filminfo = filmInfo(person_search.film_set.all())
film_graph_data = person_search.film_set.all().order_by('date')
#Step 1: Create a DataPool
return render_to_response('home/search_results.html',{'query': q, 'high': filminfo[0],
'graph_data': film_graph_data}, RequestContext(request))
except IndexError:
return render_to_response('home/not_found.html',{'query': q}, RequestContext(request))
On the homepage I also want to have a random button that displays some data from a random person on the database and display it with the above view. So far I have this view:
def random_person(request):
# 1282302 is max number of people currently
get_random = random.randint(1,1282302)
get_person = Person.objects.get(pk=get_random)
person_name = get_person.full
but I'm not sure how to complete it so it redirects to the film_chart_view.
You can redirect from random view appropriate url to the specified view as
def random_person(request):
# 1282302 is max number of people currently
get_random = random.randint(1,1282302)
get_person = Person.objects.get(pk=get_random)
person_name = get_person.full
return HttpResponseRedirect(reverse('film_chart_view')+"?q="+get_person.short)

I don't understand tests in Django, Can you help me please?

I am having a hard time with tests in Django and Python, for my final project I am making a forums website, but I don't really have any idea how or what my tests should be. Here is the views page from mysite file. Could someone please walk me through what I should test for besides if a user is logged in.
from django.core.urlresolvers import reverse
from settings import MEDIA_ROOT, MEDIA_URL
from django.shortcuts import redirect, render_to_response
from django.template import loader, Context, RequestContext
from mysite2.forum.models import *
def list_forums(request):
"""Main listing."""
forums = Forum.objects.all()
return render_to_response("forum/list_forums.html", {"forums":forums}, context_instance=RequestContext(request))
def mk_paginator(request, items, num_items):
"""Create and return a paginator."""
paginator = Paginator(items, num_items)
try: page = int(request.GET.get("page", '1'))
except ValueError: page = 1
try:
items = paginator.page(page)
except (InvalidPage, EmptyPage):
items = paginator.page(paginator.num_pages)
return items
def list_threads(request, forum_slug):
"""Listing of threads in a forum."""
threads = Thread.objects.filter(forum__slug=forum_slug).order_by("-created")
threads = mk_paginator(request, threads, 20)
template_data = {'threads': threads}
return render_to_response("forum/list_threads.html", template_data, context_instance=RequestContext(request))
def list_posts(request, forum_slug, thread_slug):
"""Listing of posts in a thread."""
posts = Post.objects.filter(thread__slug=thread_slug, thread__forum__slug=forum_slug).order_by("created")
posts = mk_paginator(request, posts, 15)
thread = Thread.objects.get(slug=thread_slug)
template_data = {'posts': posts, 'thread' : thread}
return render_to_response("forum/list_posts.html", template_data, context_instance=RequestContext(request))
def post(request, ptype, pk):
"""Display a post form."""
action = reverse("mysite2.forum.views.%s" % ptype, args=[pk])
if ptype == "new_thread":
title = "Start New Topic"
subject = ''
elif ptype == "reply":
title = "Reply"
subject = "Re: " + Thread.objects.get(pk=pk).title
template_data = {'action': action, 'title' : title, 'subject' : subject}
return render_to_response("forum/post.html", template_data, context_instance=RequestContext(request))
def new_thread(request, pk):
"""Start a new thread."""
p = request.POST
if p["subject"] and p["body"]:
forum = Forum.objects.get(pk=pk)
thread = Thread.objects.create(forum=forum, title=p["subject"], creator=request.user)
Post.objects.create(thread=thread, title=p["subject"], body=p["body"], creator=request.user)
return HttpResponseRedirect(reverse("dbe.forum.views.forum", args=[pk]))
def reply(request, pk):
"""Reply to a thread."""
p = request.POST
if p["body"]:
thread = Thread.objects.get(pk=pk)
post = Post.objects.create(thread=thread, title=p["subject"], body=p["body"],
creator=request.user)
return HttpResponseRedirect(reverse("dbe.forum.views.thread", args=[pk]) + "?page=last")
First read the Django testing documentation. You might also want to read this book. It's dated in some areas, but testing is still pretty much the same now as it was in 1.1.
It's a bit much of a topic to cover in an SO answer.
Well, you could test:
If you have the right number of pages for the objects you're paginating.
If the page you're viewing contains the right object range. If trying to access a page that doesn't exist returns the
appropriate error.
If your views for listing objects and object detail return the correct HTTP status code (200)
For starters. Hope that helps you out.

Categories