I am trying to implement django-braintree for my django-oscar project. I installed the django-braintree app and added my details in settings.py. I got a credit card details page(/payment-details). I add /pay url for a simple form. But when I am submitting it KeyError expiration_month at /payments-billing/ is coming. How do I send it to the server ?
My server side:
braintree.Configuration.configure(
braintree.Environment.Sandbox,
"****",
"****",
"****"
)
def client_token():
return braintree.ClientToken.generate()
def create_purchase(request):
nonce = request.form["payment_method_nonce"]
result = braintree.Transaction.sale({
"amount": "1000.00",
"credit_card": {
"number": "4111111111111111",
"expiration_date": "05/2020"
}
})
def pay(request):
try:
resp_dict = {}
resp_dict["client_token"] = client_token()
resp_dict["result"] = result
except Exception as e:
resp_dict["error"] = e
return TemplateResponse(request, 'django_braintree/pay_new.html', resp_dict)
My HTML:
{% block layout %}
<form id="checkout" method="post" action="/payments-billing/">
{% csrf_token %}
<div id="payment-form"></div>
<input type="submit" value="Pay $10">
</form>
{% endblock %}
{% block scripts %}
<script src="https://js.braintreegateway.com/v2/braintree.js"></script>
<script>
braintree.setup(
// Replace this with a client token from your server
"{{ client_token }}",
"dropin", {
container: "payment-form"
});
</script>
{% endblock %}
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
The third-party django-braintree library is not currently compatible with the Braintree Drop-In. The Drop-In only supports expiration_date while the form in the library expects expiration_month and expiration_year, causing the KeyError you're getting. This library has also not been updated to use payment method nonces. I would not recommend using this library, but instead write your own django integration to Braintree using our Python client library.
Related
I wanted to use HTMX to show messages from django backend after a lot of trial and error I ended up with a working solution, that I want to leave behind for anyone looking for it - also, please feel free to post your suggestions. Unfortunately, besides a little example from the htmx-django package, there is almost no tutorial material available. Be sure to check the example out, as it covers some basics specially for django users!
For HTMX we need a little element somewhere in the DOM that HTMX can work (swap for example) with. Place for example a
<div id="msg">
{% include "app/messages-partial.html" %}
</div>
somewhere on your index.html. Now we want to use this element to fill it with content, if the need arises. Let's say we click a button, that communicates with a view and the answer gets posted. In django the response is created using render:
class TestView(TemplateView):
template_name = "index.html"
def get(self, request, *args, **kwargs):
...
class_code = """class='alert alert-dismissible fade show'"""
msg_str = """testmessage"""
msg_btn = """<button type='button' class='close' data-dismiss='alert'>x</button>"""
msg = mark_safe(f"""<div {classcode}>{msg_str}{msg_btn}</div>""")
return render(request, "app/messages-partial.html", {"msg": msg})
and a corresponding path in urls.py:
path("action/", views.TestView.as_view(), name = "test"),
I created a simple messages-partial.html:
{% if msg %}
{{ msg }}
{% endif %}
So what I wanted is, when I triggered the the view, the {{ msg }} gets replaced (swapped) by HTMX to the content of the response. Therefore I implement the HTMX part somewhere else on the index.html as follows:
<div class="..."
hx-get="/action"
hx-swap="innerHTML"
hx-target="#msg" >
<button class="btn btn-primary">TEST</button>
</div>
The former <div id="msg">...</div> will swap with {{ msg }} (and I included the typical django-messages close button).
Thanks to the htmx discord channel where friendly people shared their knowledge with me.
I am suppose to add forms to my HTML to allow users to add data (comments to my page) and also store the data via GAE-Datastore. I have been able to store the data but not able to get the user comments posted to the main page.
Seperate code files:
index.yaml
indexes:
- kind: Section
ancestor: yes
properties:
- name: date
direction: desc
app.yaml
application: addnotes
version: 1
runtime: python27
api_version: 1
threadsafe: true
# [START handlers]
handlers:
- url: /stylesheets
static_dir: stylesheets
- url: /.*
script: addnotes.app
# [END handlers]
# [START libraries]
libraries:
- name: webapp2
version: latest
- name: jinja2
version: latest
# [END libraries]
addnotes.py
import os
import urllib`
from google.appengine.api import users
from google.appengine.ext import ndb
import jinja2
import webapp2
JINJA_ENVIRONMENT = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
extensions=['jinja2.ext.autoescape'],
autoescape=True)`
DEFAULT_SECTION_NAME = 'General_Submission'
# We set a parent key on the 'Comment' to ensure that they are all
# in the same entity group. Queries across the single entity group
# will be consistent. However, the write rate should be limited to
# ~1/second.
def section_key(section_name=DEFAULT_SECTION_NAME):
"""Constructs a Datastore key for a Section entity.
We use section_name as the key.
"""
return ndb.Key('Section', section_name)`
# [START comment]
# These are the objects that will represent our Author and our Post. We're using
# Object Oriented Programming to create objects in order to put them in Google's
# Database. These objects inherit Googles ndb.Model class.
class Author(ndb.Model):
"""Sub model for representing an author."""
identity = ndb.StringProperty(indexed=True)
email = ndb.StringProperty(indexed=False)
class Comment(ndb.Model):
"""A main model for representing an individual Guestbook entry."""
author = ndb.StructuredProperty(Author)
content = ndb.StringProperty(indexed=False)
date = ndb.DateTimeProperty(auto_now_add=True)
# [END comment]
class Handler(webapp2.RequestHandler):
"""
Basic Handler; will be inherited by more specific path Handlers
"""
def write(self, *a, **kw):
"Write small strings to the website"
self.response.out.write(*a, **kw)
def render_str(self, template, **params):
"Render jija2 templates"
t = JINJA_ENVIRONMENT.get_template(template)
return t.render(params)
def render(self, template, **kw):
"Write the jinja template to the website"
self.write(self.render_str(template, **kw))
# [START main_page]
class MainPage(webapp2.RequestHandler):
def get(self):
section_name = self.request.get('section_name', DEFAULT_SECTION_NAME)
if section_name == DEFAULT_SECTION_NAME.lower(): section_name = DEFAULT_SECTION_NAME
comments_query = Comment.query(ancestor=section_key(section_name)).order(-Comment.date)
comment = comments_query.fetch(10)
# If a person is logged in to Google's Services
user = users.get_current_user()
if user:
url = users.create_logout_url(self.request.uri)
url_linktext = 'Logout'
else:
user = 'Anonymous Poster'
url = users.create_login_url(self.request.uri)
url_linktext = 'Login'
template_values = {
'user': user,
'comment': comment,
'section_name': urllib.quote_plus(section_name),
'url': url,
'url_linktext': url_linktext,
}
template = JINJA_ENVIRONMENT.get_template('notes.html')
self.response.write(template.render(template_values))
# [END main_page]
# [START Comment Submission]
class Section(webapp2.RequestHandler):
def post(self):
# We set a parent key on the 'Comment' to ensure that they are all
# in the same entity group. Queries across the single entity group
# will be consistent. However, the write rate should be limited to
# ~1/second.
section_name = self.request.get('section_name', DEFAULT_SECTION_NAME)
comment = Comment(parent=section_key(section_name))
if users.get_current_user():
comment.author = Author(
identity=users.get_current_user().user_id(),
email=users.get_current_user().email())
# Get the content from our request parameters, in this case, the message
# is in the parameter 'content'
comment.content = self.request.get('content')
# Write to the Google Database
comment.put()
query_params = {'section_name': section_name}
self.redirect('/?' + urllib.urlencode(query_params))
#[END Comment Submission]
app = webapp2.WSGIApplication([
('/', MainPage),
('/section', Section),
], debug=True)
notes.html (an excerpt to test out comment functionality)
<!DOCTYPE html>
{% autoescape true %}
<html>
<head>
<meta charset="UTF-8">
<title>Project Stage 4</title>
</head>
<body>
<h3>User Comments</h3>
<div>
{{ url_linktext }}
<form>Section Title:
<input value="{{ section_name }}" name="section_name">
<input type="submit" value="switch">
</form>
<br><br>
<form action="/section?section_name={{ section_name }}" method="post">
<div>
<label>Comment: <textarea name="content" rows="5" cols="60"></textarea></label>
</div>
<input type="submit" value="Submit Comment">
</form>
<hr>
{% for content in comment %}
{% if comment.content %}
<b>{{ comment.author.email }}
{% if user and user.user_id() == comment.author.identity %}
(You)
{% endif %}
</b> wrote:
{% else %}
An anonymous person wrote:
{% endif %}
<blockquote>{{ comment.content }}</blockquote>
{% endfor %}
</div>
</body>
</html>
{% endautoescape %}
You've confused yourself with the way you've named your variables. You send the list of comments to the template as "comment", then iterate through that using "content" for each item, but then revert back to using "comment" instead.
You should give your things logical names that reflects what they are. In your handler:
comments_query = Comment.query(ancestor=section_key(section_name)).order(-Comment.date)
comments = comments_query.fetch(10)
...
template_values = {
...
'comments': comments,
...
}
and in your template:
{% for comment in comments %}
{% if comment.content %}
<b>{{ comment.author.email }}
...
I've built a password reset function for a django system that is exposed through a tastypie api. The rendering process looks like this
form = PasswordResetForm({'email': reset_email})
form.full_clean()
form.save({
'use_https': request.is_secure(),
'token_generator': default_token_generator,
'from_email': settings.DEFAULT_FROM_EMAIL,
'email_template_name': 'registration/password_reset_email.html',
'request': request
})
return self.create_response(request, { 'success': True })
I've used the standard Django password reset email template. When I call the endpoint, the http request gets rendered in some of the custom tags e.g
Markup:
{% trans "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url 'django.contrib.auth.views.password_reset_confirm' uidb36=uid token=token %}
{% endblock %}
{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}
Expected result:
Please go to the following page and choose a new password:
httt://www.myurl.com/password-reset
"Your username, in case you've forgotten: User Name
Actual result
Please go to the following page and choose a new password:
httt://{'request': , POST:, COOKIES:{}, META:{'CONTENT_LENGTH': '48', (...)
"Your username, in case you've forgotten: User Name
It strikes me as odd that the model based template tags render correctly, but the global ones (e.g. 'Site_name') and the reset url & token seem to break. I'm sure that's a good clue as to the cause of the problem, but I don't know where to go next.
Would be great if anyone can help.
Thanks
I am trying out to build full-text searching by using sphinx search, postgresql & django based on this tutorial: http://pkarl.com/articles/guide-django-full-text-search-sphinx-and-django-sp/.
All setup done for sphinx & postgresql and it works but I got trouble when reach on Sample Django code part.
In django views & urlconf, I only changed the function of *search_results* into search and Story model with my own model. For URLConf, I only changed *search_results* into search just same like on views and nothing changed made on search template.
So when I try to search from my form in Django, I get exception:
TypeError at /search/
list() takes exactly 1 argument (0 given)
I also try to changed based on steyblind's comment by change the urlpattern & view definition like this:
(r'^search/(.*)?', search),
def search(request, query=''):
but still keep get TypeError exception.
Is there any mistake I am doing here? Thanks in advance.
Here's my snippets:
Urls.py
(r'^search/(.*)', search),
Views.py
def search(request, query):
try:
if(query == ''):
query = request.GET['query']
results = Flow.search.query(query)
context = { 'flows': list(results),'query': query, 'search_meta':results._sphinx }
except:
context = { 'flows': list() }
return render_to_response('search.html', context, context_instance=RequestContext(request))
search.html
{% extends "base.html" %}
{% block main %}
<div>
<form action="/search/" method="GET">
<input type="text" name="query"/>
<input type="submit">
</form>
{% if flows %}
<p>Your search for “<strong>{{ query }}</strong>” had <strong>{{ search_meta.total_found }}</strong> results.</p>
<p>search_meta object dump: {{ search_meta }}</p>
{% endif %}
<hr/>
{% for s in flows %}
<h3>{{ s.title }}</h3>
<p>(weight: {{ s.sphinx.weight }})</p>
<p>story.sphinx object dump: {{ s.sphinx }}</p>
{% empty %}
<p>YOU HAVEN'T SEARCHED YET.</p>
{% endfor %}
</div>
{% endblock %}
Correct me if I'm wrong, but Django-Sphinx seems to be an abandoned project. The last update to it was a year ago, with most updates being 3-5 years ago. Also, I cannot speak for Django then, but it can do now, out of the box, what you are trying to do with Sphinx.
What version of Django and Python are you using? The error you are getting is strange as list() can take no arguments. Try this in a python shell:
>> list()
[]
Regardless, I've made a few modifications to the code that could possibly help fix the issue. However, if there are no results, you are passing 'flows' as empty in this line:
context = { 'flows': list() }
If you look at the template, this really accomplishes nothing.
urls.py:
(r'^search/', search),
views.py:
def search(request):
query = request.GET.get('query')
if query:
results = Flow.search.query(query)
if results:
context = { 'flows': list(results),'query': query, 'search_meta':results._sphinx }
else:
context = { 'flows': list() }
return render_to_response('search.html', context, context_instance=RequestContext(request))
All that said, I'd highly suggest that since this project is so outdated that you use your own search. Or if you need more functionality, you could use a search app like Haystack which is updated frequently. Using the same urls.py as above, you could implement the below as an easy search that will return all results for a blank search, the actual filtered results for a query.
views.py:
def search(request):
query = request.GET.get('q')
results = Flow.objects.all()
if query:
results = results.query(query)
return render_to_response('search.html', {"flows": results,}, context_instance=RequestContext(request))
I'm using Django 1.4 with Python 2.7 on Ubuntu 12.04.
I have a template that I want to fill with information regarding developers working on a project.
Each developer will have the following information to display:
type
title
first_name
last_name
skills
The trouble I'm running into is that each developer has many skills associated with them.
I've created the model like this:
class DevSkills(models.Model):
dev = models.ForeignKey(User)
skill = models.CharField(max_length = 200)
I'm trying to create a view that will populate the dictionary so that I can loop through each developer, display their info, then loop through each skill (to display them one at a time).
Here is the view:
def developers(request):
"""
.. function:: developers()
Provide the page that shows the developer credentials
:param request: Django Request object
"""
devs = User.objects.filter(is_staff = True)
dev_info = {}
for dev in devs:
dev_info.update(createDevDisplayDict(dev))
data = { 'user' : request.user }
data.update({ 'devs' : dev_info })
return render_to_response("developers.html", data)
I've designated the is_staff field from User to indicate the user is a developer.
I've created a simple utility that helps me populate the embedded dictionaries so I can loop through them:
def createDevDisplayDict(user):
"""
.. function:: createDevDisplayDict()
Create a dictionary for showcasing the developer
:param user: developer who we are working with
"""
userProfile = UserProfile.objects.get(user = user)
devSkills = DevSkills.objects.filter(dev = user)
dev_dict = {}
user_dict = { 'dev_type' : userProfile.dev_type,
'title' : userProfile.title,
'first_name' : user.first_name,
'last_name' : user.last_name,
}
dev_dict.update(user_dict)
skill_dict = {}
for skill in devSkills:
skill_dict.upate({ 'skill' : skill.skill })
dev_dict.update(skill_dict)
return dev_dict
My intention is to loop through each developer, create a "super" dictionary to contain each of their user_dict dictionaries (which are based on their User info) and add to that a dictionary for each of their skills. Then, back in the template I want to loop through the "super" dictionary in such a way that it will present them something like the following:
James Taylor
Project Lead
Software Developer
• Django
• Python
• JavaScript
• JQuery
Elizabeth Norton
Design Lead
Graphic Designer
• Edge
• Adobe Photoshop
• Adobe Illustrator
• CSS
Here is the template I'm trying to work with:
{% extends "base.html" %}
{% block content %}
<div>
<p>Our Developers</p>
</div>
{% for dev in devs %}
{{ dev.user_dict.first_name }} {{ dev.user_dict.last_name }}
{{ dev.user_dict.title }}
{{ dev.user_dict.dev_type }}
<ul>
{% for skill in dev.skill_dict %}
<li>skill.skill</li>
{% endfor %}
</ul>
{% endfor %}
{% endblock %}
When I see the page now it looks like this:
Our Developers
Yeah...nothing is getting populated. Any suggestions?
UPDATE 1:
I've modified my utility per iMom0's suggestion. I'm now using a list to contain each skill. Like so:
def createDevDisplayDict(user):
"""
.. function:: createDevDisplayDict()
Create a dictionary for showcasing the developer
:param user: developer who we are working with
"""
userProfile = UserProfile.objects.get(user = user)
devSkills = DevSkills.objects.filter(dev = user)
dev_dict = {}
user_dict = { 'dev_type' : userProfile.dev_type,
'title' : userProfile.title,
'first_name' : user.first_name,
'last_name' : user.last_name,
}
dev_dict.update(user_dict)
skills = []
for skill in devSkills:
skills.append(skill.skill)
skill_dict = {'skill' : skills}
dev_dict.update(skill_dict)
return dev_dict
I can see the value in doing this - in fact, it's much more intuitive and I think I was making it too hard the other way. But my template still shows up bare. :(
UPDATE 2:
I know I'm on the write path now. I put some logging in the view:
devs = User.objects.filter(is_staff = True, is_superuser = False)
dev_info = {}
for dev in devs:
dev_info.update(createDevDisplayDict(dev))
for key in dev_info:
for sub_key in dev_info[key]:
logfile.write('{0} = {1}\n'.format(sub_key, dev_info[key][sub_key]))
And the logfile displays:
skills = [u'Java', u'Perl', u'C++', u'Python', u'Django']
dev_type = Software Developer
first_name = Rico
last_name = Cordova
title = Owner
So, it has to be a way I'm calling it in the template, right?
UPDATE 3:
I had a realization that I was disconnecting the user_dict and their skills. So I modified the utility slightly to bring them into a single dictionary.
## Create a logging object
userProfile = UserProfile.objects.get(user = user)
devSkills = DevSkills.objects.filter(dev = user)
dev_dict = {}
user_dict = { 'dev_type' : userProfile.dev_type,
'title' : userProfile.title,
'first_name' : user.first_name,
'last_name' : user.last_name,
}
skills = []
for skill in devSkills:
skills.append(skill.skill)
user_dict.update({ 'skills' : skills })
dev_dict['user_dict'] = user_dict
return dev_dict
This is a much better solution, in my opinion. I'm still having trouble accessing the user_dict info in the template though. :(
You could be using Django's ORM features to make this a lot easier (and, we'll see, get better performance), it's a great feature!
Model code
class DevSkill(models.Model):
dev = models.ForeignKey(UserProfile, related_name = 'skill_set')
skill = models.CharField(max_length = 200)
We changed two things:
Using a UserProfile ForeignKey instead of user will simplify the rest of the code. Since you have a UserProfile <-> User mapping anyway, this is not going to be an issue.
We added a related_name attribute so that any UserProfile object now has a skill_set attribute which store it's list of DevSkills.
(Please note that related_name is not required, and Django will create a generic modelname_set attribute if you don't set it).
Also, DevSkill should be singular, the object is a single skill!
I also expect that you have the following for UserProfile, and created code assuming you did. You'll need to adapt if you don't.
class UserProfile(models.Model):
user = models.OneToOneField(User)
title = models.CharField(max_length = 40)
dev_type = # W/E you want
In the view:
devs = UserProfile.objects.all() # Or W/E queryset would fit.
# Pass context & all.
In the template:
{% extends "base.html" %}
{% block content %}
<div>
<p>Our Developers</p>
</div>
{% for dev in devs %}
{{ dev.user.first_name }} {{ dev.user.last_name }}
{{ dev.title }}
{{ dev.dev_type }}
<ul>
{% for skill in dev.skill_set.all %}
<li>skill.skill</li>
{% endfor %}
</ul>
{% endfor %}
{% endblock %}
Performance
Please be aware that this code (the one you're using now too, though) is going to absolutely kill performance. Indeed, we're doing several queries for each user (Hitting the database for their User and their DevSkills).
That's not a problem though, we can use the ORM's select_related and prefetch_related features to solve that issue:
devs = UserProfile.objects.select_related('user').prefetch_related('skill_set').all()
That way, we only do two queries, one for the UserProfile -> Userand one for the DevSkill's, for which the joining is done in Python, but you shouldn't care about that, Django does it for you.
Please be aware that prefetch_related is a Django 1.4 feature.
Footnote: the UserProfile stuff is going away in Django 1.5, check it out!
dict.update always overwrite the value of dict
In [2]: d = {'key': 'value'}
In [3]: d.update({'key': 'value1'})
In [4]: d
Out[4]: {'key': 'value1'}
Instead, you should use list and list.append.
And your template do not know what user_dict is, correct it,
dev_dict['user_dict'] = user_dict
This is a new concept for me - dict.items in a template. The following is exactly how I was able to display what I wanted.
{% extends "base.html" %}
{% block content %}
<div>
<p>Our Developers</p>
</div>
{% for key, value in devs.items %}
{{ value.first_name }} {{ value.last_name }} <br>
{{ value.title }} <br>
{{ value.dev_type }} <br>
<ul>
{% for skill in value.skills %}
<li>{{ skill }}</li>
{% endfor %}
</ul>
{% endfor %}
{% endblock %}