Using the Stripe API to create a credit card checkout form on my website.
I am trying to test the following line in my view.py of the app checkout.
print (request.user.userStripe.stripe_id)
It could be the way my Users is set up.. I tried importing the models from the user app. I just don't understand why it can't see it.
I have two apps: users and checkout
I am the following error in the debug page
AttributeError at /checkout/
'User' object has no attribute 'userStripe'
Request Method: GET
Request URL: http://127.0.0.1:8000/checkout/
Django Version: 1.11
Exception Type: AttributeError
Exception Value:
'User' object has no attribute 'userStripe'
Exception Location: /home/dominic/Desktop/Projects/decentraland/website/manaland/manaland/env/lib/python3.4/site-packages/django/utils/functional.py in inner, line 239
Python Executable: /home/dominic/Desktop/Projects/decentraland/website/manaland/manaland/env/bin/python
Python Version: 3.4.3
Python Path:
['/home/dominic/Desktop/Projects/decentraland/website/manaland/manaland',
'/home/dominic/Desktop/Projects/decentraland/website/manaland/manaland/env/lib/python3.4',
'/home/dominic/Desktop/Projects/decentraland/website/manaland/manaland/env/lib/python3.4/plat-x86_64-linux-gnu',
'/home/dominic/Desktop/Projects/decentraland/website/manaland/manaland/env/lib/python3.4/lib-dynload',
'/usr/lib/python3.4',
'/usr/lib/python3.4/plat-x86_64-linux-gnu',
'/home/dominic/Desktop/Projects/decentraland/website/manaland/manaland/env/lib/python3.4/site-packages']
Server time: Mon, 2 Jul 2018 22:38:35 +0000
checkout.views.py
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from users.models import User, profile, userStripe
from django.views import generic
from django.views.generic import CreateView
#TODO UPDATE WITH LIVE VERISON FOR STRIPE API KEYS
import stripe
stripe.api_key = settings.STRIPE_SECRET_KEY
# Create your views here.
#login_required
def checkout(request):
publishKey = settings.STRIPE_PUBLISHABLE_KEY
print (request.user.userStripe.stripe_id)
if request.method == 'POST':
token = request.POST['stripeToken']
# Token is created using Checkout or Elements!
# Get the payment token ID submitted by the form:
try:
charge = stripe.Charge.create(
amount=999,
currency='usd',
description='Example charge',
source=token,
)
except stripe.error.CardError as e:
pass
context = {'publishKey': publishKey}
template = 'checkout/checkout.html'
return render(request, template, context)
users.models.py
from django.contrib.auth.models import AbstractUser
from django.core.urlresolvers import reverse
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from allauth.account.signals import user_logged_in, user_signed_up
import stripe
stripe.api_key = settings.STRIPE_SECRET_KEY
#python_2_unicode_compatible
class User(AbstractUser):
# First Name and Last Name do not cover name patterns
# around the globe.
name = models.CharField(_('Name of User'), blank=True, max_length=255)
bio = models.CharField( blank=True, max_length=255)
image = models.ImageField(null=True, blank=True)
def __str__(self):
return self.username
def get_absolute_url(self):
return reverse('users:detail', kwargs={'username': self.username})
class profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
description = models.CharField( blank=True, max_length=255)
image = models.ImageField(null=True, blank=True)
def __str__(self):
return self.user.username
class userStripe(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
stripe_id = models.CharField(max_length=200, null=True, blank=True)
def __unicode__(self):
if self.stripe_id:
return str(self.stripe_id)
else:
return self.user.username
def stripeCallback(sender, request, user, **kwargs):
user_stripe_account, created = userStripe.objects.get_or_create(user=user)
if created:
print ('created for %s'%(user.username))
if user_stripe_account.stripe_id is None or user_stripe_account.stripe_id == '':
new_stripe_id = stripe.Customer.create(email=user.email)
user_stripe_account.stripe_id = new_stripe_id['id']
user_stripe_account.save()
def profileCallback(sender, request, user, **kwargs):
userProfile, is_created = profile.objects.get_or_create(user=user)
if is_created:
userProfile.name = user.username
userProfile.save()
user_logged_in.connect(stripeCallback)
user_signed_up.connect(profileCallback)
user_signed_up.connect(stripeCallback)
You should use lowercase model name, print(request.user.userstripe.stripe_id).
Better set related_name in your OneToOneField so you will know exactly how to access userStripe from user.
class userStripe(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='user_stripe')
...
print(request.user.user_stripe.stripe_id)
Use request.user.userStripe.stripe_id.
You are using request.User. Instead you have to use: request.user.
you miss typing userStripe in print (request.user.userStripe.stripe_id)
try write userstripe :
print (request.user.userstripe.stripe_id)
it worked for me very nice
Related
I am working on an app with Django backend and I am currently developing the signup page. Here's my code:
models.py
from django.db import models
from django.contrib.auth.models import User
from django.core.validators import MaxValueValidator, MinValueValidator
from datetime import date
from .countries import COUNTRIES
from .hobbies import HOBBIES
class Hobbies(models.Model):
hobby = models.CharField(max_length=255, choices=HOBBIES)
class Profile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
def username(self):
usern = User.objects.get(id=self.user.id)
usern = usern.username
return usern
setup = models.BooleanField(default=False)
gender = models.CharField(max_length=100, blank=True)
dob = models.DateField(blank=True)
def age(self):
today = date.today()
age = today.year - self.dob.year - ((today.month, today.day) < (self.dob.month, self.dob.day))
return age
orgin = models.CharField(max_length=300, choices=COUNTRIES, blank=True)
lives = models.CharField(max_length=300, choices=COUNTRIES, blank=True)
bio = models.CharField(max_length=150, blank=True)
email = models.CharField(max_length=255, blank=True)
image = models.ImageField(upload_to='images', blank=True)
hobbie = models.ManyToManyField('Hobbies', blank=True)
views.py-
from django.shortcuts import render
from rest_framework import viewsets, status
from .serializers import UserSerializer, ProfileSerializer
from .models import Profile
from django.db import IntegrityError
from rest_framework.response import Response
from rest_framework.decorators import action
from django.contrib.auth.models import User
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.permissions import IsAuthenticatedOrReadOnly, BasePermission
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json
from django.contrib.auth import authenticate
# Create your views here.
#.....
#csrf_exempt
def signup(request):
if request.method == 'POST':
data = json.loads(request.body)
username = data.get("username", "")
password = data.get("password", "")
try:
user = User.objects.create_user(username, '',password)
user.save()
created = True
profile = Profile.objects.create(user=user)
profile.save()
except IntegrityError:
created = False
return JsonResponse(created, safe=False)
Everything works when I try to create a new user without creating a new profile. But when I try to create a Profile when I am creating the User I get an "IntegrityError.": "NOT NULL constraint failed: home_profile.dob" .How can I fix this?
Your problem lies here:
dob = models.DateField(blank=True)
DateFields, if empty, are rendered as null in the database, so you need to add
dob = models.DateField(blank=True, null=True)
As a rule of thumb, blank=True says the field need not be filled in for forms. null=True says the database can accept a null value. The exception is for string types, eg CharField and TextField, which only use blank=True as django saves an empty string, "", rather than a null value.
I'm following a tutorial on Django in Python, I'm trying to add a bio to my user profile page, however I get this error:
OperationalError at /admin/users/profile/
no such column: users_profile.bio
Here is my models.py file:
from django.contrib.auth.models import User
# Create your models here.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
bio = models.TextField(User)
def __str__(self):
return f'{self.user.username} Profile'
Here is my admin.py file:
from django.contrib import admin
from .models import Profile
# Register your models here.
admin.site.register(Profile)
Just change def __str(self):
def __str__(self):
return str(self.user.user)
OR
def __str__(self):
return 'Check if it is the problem'
Enter image description here error image screenshot
Here is my models.py:
from django.db import models
class country (models.Model):
country_name = models.CharField(max_length=200, null=True)
def __str__(self):
return self.country_name
class state (models.Model):
state_name = models.CharField(max_length=200, null=True)
country = models.ForeignKey(country, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.state_name
class city (models.Model):
city_name = models.CharField(max_length=200, null=True)
country = models.ForeignKey(country, on_delete=models.CASCADE, null=True)
state = models.ForeignKey(state, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.city_name
class publication(models.Model):
title= models.CharField(max_length=300, null=True)
country=models.ForeignKey(country, on_delete=models.CASCADE, null=True)
state=models.ForeignKey(state, on_delete=models.CASCADE, null=True)
city=models.ForeignKey(city, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.title
Here is my seralizers.py:
from rest_framework import routers, serializers, viewsets
from .models import *
from django.contrib.auth.models import User
from rest_framework import permissions
class publicationSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = publication
fields = '__all__'
Here is my view.py:
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from .models import *
from .serializers import *
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status,mixins,generics
from django.http import Http404
from rest_framework import renderers
class SnippetHighlight(APIView):
# def get(self,request):
def get(self, request):
queryset = publication.objects.select_related('country','state','city')
serializer_class = publicationSerializer(queryset,many=True,
context={'request': request})
return Response(serializer_class.data)
Here is my urls.py:
from django.conf.urls import url, include
from django.contrib import admin
from rest_framework.urlpatterns import format_suffix_patterns
from api.models import *
from api import views
# from api.serializers import UserSerializer
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^snippets/', views.SnippetHighlight.as_view()),
# url(r'^users/$', views.UserList.as_view()),
# url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
# url(r'^api-auth/', include('rest_framework.urls')),
]
urlpatterns = format_suffix_patterns(urlpatterns)
It is showing error:
AssertionError at /snippets/
`HyperlinkedIdentityField` requires the request in the serializer context. Add `context={'request': request}` when instantiating the serializer.
Request Method: GET
Request URL: http://127.0.0.1:8000/snippets/
Django Version: 1.11.15
Exception Type: AssertionError
Exception Value:
`HyperlinkedIdentityField` requires the request in the serializer context. Add `context={'request': request}` when instantiating the serializer.
Exception Location: /home/soubhagya/Desktop/rest/env/local/lib/python2.7/site-packages/rest_framework/relations.py in to_representation, line 356
Python Executable: /home/soubhagya/Desktop/rest/env/bin/python
Python Version: 2.7.12
Python Path:
['/home/soubhagya/Desktop/rest',
'/home/soubhagya/Desktop/rest/env/lib/python2.7',
'/home/soubhagya/Desktop/rest/env/lib/python2.7/plat-x86_64-linux-gnu',
'/home/soubhagya/Desktop/rest/env/lib/python2.7/lib-tk',
'/home/soubhagya/Desktop/rest/env/lib/python2.7/lib-old',
'/home/soubhagya/Desktop/rest/env/lib/python2.7/lib-dynload',
'/usr/lib/python2.7',
'/usr/lib/python2.7/plat-x86_64-linux-gnu',
'/usr/lib/python2.7/lib-tk',
'/home/soubhagya/Desktop/rest/env/local/lib/python2.7/site-packages',
'/home/soubhagya/Desktop/rest/env/lib/python2.7/site-packages']
Server time: Sun, 23 Sep 2018 10:09:39 +0000
It is coming in the shell but not coming in browser
The error message says exactly what's wrong.
HyperlinkedIdentityField requires the request in the serializer
context. Add context={'request': request} when instantiating the
serializer.
There is also an example of HyperlinkedModelSerializer in Django Rest Framework documentation where you can see it in use:
serializer = AccountSerializer(queryset, context={'request': request})
Add context={'request': request} when instantiating the serializer as the error message says.
serializer_class = publicationSerializer(queryset,many=True,
context={'request': request})
just as the error message is clearly saying:
HyperlinkedIdentityField requires the request in the serializer context. Add context={'request': request} when instantiating the serializer.
I am trying to create a shopping cart for my website, but in my function "add_to_cart" when I try to request the user profile model in the beginning of function it tells me
'User' object has no attribute 'profile'
add_to_cart is the first method in Checkout views.py under #get the user profile
Error
AttributeError at /checkout/add-to-cart/2/
'User' object has no attribute 'profile'
Request Method: GET
Request URL: http://127.0.0.1:8000/checkout/add-to-cart/2/
Django Version: 1.11
Exception Type: AttributeError
Exception Value:
'User' object has no attribute 'profile'
If I remove the related_name for user in Profile, then I receive this error:
Error from removal of related_name
Request Method: GET
Request URL: http://127.0.0.1:8000/checkout/add-to-cart/2/
Django Version: 1.11
Exception Type: AttributeError
Exception Value:
'Product' object has no attribute 'all'
Checkout views.py
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import login_required
from django.urls import reverse
from django.shortcuts import render, redirect, get_object_or_404
from users.models import User, Profile, userStripe
from portal.models import Product
#from manaland.helper import get_reference_code
from checkout.extras import generate_order_id
from checkout.models import OrderItem, Order
from django.views import generic
from django.views.generic import CreateView
import stripe
stripe.api_key = settings.STRIPE_SECRET_KEY
def add_to_cart(request, **kwargs):
#get the user Profile
user_Profile = get_object_or_404(Profile, user=request.user)
#filter products for id
product = Product.objects.filter(id=kwargs.get('item_id', "")).first()
#check if the user already owns the product
if product in request.user.profile.merchandise.all():
messages.info(request, "You already own this product")
return redirect(reverse('product_list'))
#create OrderItem of the selected product
order_item, status = OrderItem.objects.get_or_create(product=Product)
#create order associate with the user
user_order, status = Order.objects.get_or_create(owner=user_Profiles, is_ordered=False)
user_order.items.add(order_item)
if status:
#generate a reference code
user_order.ref_code = generate_order_id()
user_order.save()
#show confirmataion message and redirect to same page
messages.info(request, "item added to cart")
return redirect(reverse('product_list'))
def delete_from_cart(request, item_id, LoginRequiredMixin):
item_to_delete = OrderItem.objects.filter(pk=item_id)
if item_to_delete.exists():
item_to_delete[0].delete()
messages.info(request, "Item has been removed from shopping cart")
return redirect(reverse('shopping_cart:order_summary'))
def order_details(request, LoginRequiredMixin, **kwargs):
existing_order = get_user_pending_order(request)
context = {
'order': existing_order
}
return render(request, 'checkout/order_summary', context)
#class UserDetailView(LoginRequiredMixin, DetailView):
# model = User
# These next two lines tell the view to index lookups by username
# slug_field = 'username'
# slug_url_kwarg = 'username'
def checkout(request, LoginRequiredMixin):
existing_order = get_user_pending_order(request)
context = {
'order': existing_order
}
return render(request, 'checkout/checkout', context)
def update_transaction_records(request, order_id):
#get the order being processed
order_to_purchase = Order.objects.filter(pk=order_id).first()
#update the placed order
order_to_purchase.is_ordered=True
order_to_purchase.date_ordered=datetime.datetime.now()
order_to_purchase.save()
#get all items in the order
order_items = order_to_purchase.items.all()
order_items.update(is_ordered=True, date_ordered=datetime.datetime.now())
#add products to use profile
user_Profiles = get_object_or_404(Profile, user=request.user.user_profile)
#get the product from the items
order_products = [item.product for item in order_items]
user_Profiles.merchandise.add(*order_products)
user_Profiles.save()
#TODO Update payment records
#TODO email customer
messages.info(request, "Thank you! Your items have been added to your account")
return redirect(reverse('users:detail'))
def success(request, **kwargs):
return render(request, 'checkout/purchase_success.html', {})
Users models.py
from django.contrib.auth.models import AbstractUser
from django.core.urlresolvers import reverse
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from allauth.account.signals import user_logged_in, user_signed_up
import stripe
stripe.api_key = settings.STRIPE_SECRET_KEY
from portal.models import Product
#from django.apps import apps
#Product1 = apps.get_model('portal', 'Product')
class User(AbstractUser):
# First Name and Last Name do not cover name patterns
# around the globe.
name = models.CharField(_('Name of User'), blank=True, max_length=255)
bio = models.CharField( blank=True, max_length=255)
image = models.ImageField(null=True, blank=True)
def __str__(self):
return self.username
def get_absolute_url(self):
return reverse('users:detail', kwargs={'username': self.username})
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='user_profile')
merchandise = models.OneToOneField(Product, blank=True, null=True)
description = models.CharField( blank=True, max_length=255)
image = models.ImageField(null=True, blank=True)
def __str__(self):
return self.user.username
Checkout urls.py
from django.conf import settings
from django.conf.urls.static import static
from django.conf.urls import url
from . import views
from manaland.views import ProductListView
from .views import (
add_to_cart,
delete_from_cart,
order_details,
checkout,
update_transaction_records,
success
)
#NOTE: https://github.com/codingforentrepreneurs/Guides/blob/master/all/common_url_regex.md
urlpatterns = [
#Shopping Cart
url(r'^add-to-cart/(?P<item_id>[-\w]+)/$', views.add_to_cart, name='add_to_cart'),
url(r'^order-summary/$', order_details, name='order_summary'),
url(r'^success/$', success, name='purchase_success'),
url(r'^item/(?P<item_id>[-\w]+)/delete/$', delete_from_cart, name='delete_item'),
url(r'^checkout/$', checkout, name='checkout'),
#url(r'^payment/(?P<order_id>[-\w]+)/update/$', process_payment, name='process_payment'),
url(r'^update-transaction/(?P<order_id>[-\w]+)/$', update_transaction_records, name='update_records'),
#url(r'^tip/create/$', views.TipCreate.as_view(), name='tip_create'),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Your profile model is related to your User model via the user_profile related name, so the correct way to query it would be:
...
if product in request.user.user_profile.merchandise.all():
...
if for any reason you want to rename this relationship, then:
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='profile')
Then, your merchandise relationship is One to One, so it would return an object, not a collection, no need for all:
...
if product in request.user.user_profile.merchandise:
...
One improvement you can make here, is because merchandise is another object, this lookup will hit the database again just to see if merchandise exist. To save you a database hit, you can use the Profile auto-field merchandise_id, to read the information saved on the Profile table instead:
...
if product in request.user.user_profile.merchandise_id:
...
Every relationship (ForeignKey, ManyToMany and OneToOne) will create those auto-fields in the forwarding model, so it's easy to ask if the related object exist without having to invoke it.
I know you're having trouble getting all the concepts of the Django ORM in your head, so I recommend you read this documentation page throughly, it covers all the different relationships and concepts that are basic to a successful Django project.
I'm having issue with the get_or_create statement. It gets the record if there is one but isnt creating a record. I have defaults in all of my model fields.
My view.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, HttpResponseRedirect, Http404, get_object_or_404
from django.contrib.auth import logout, login, authenticate
from django.contrib.auth.models import User
from django.contrib import messages
from django.core.urlresolvers import reverse
from django.utils.safestring import mark_safe
# Create your views here.
from .models import UserProfile
#login_required
def profile_view(request):
user = request.user
account = request.user
profile = UserProfile.objects.get_or_create(UserProfile, user=user)
context = {'profile': profile, 'account': account, }
template = 'profiles/profile.html'
return render(request, template, context)
The traceback im getting is:
ypeError at /profiles/
get_or_create() takes exactly 1 argument (3 given)
Request Method: GET
Request URL: http://127.0.0.1:8000/profiles/
Django Version: 1.6.5
Exception Type: TypeError
Exception Value:
get_or_create() takes exactly 1 argument (3 given)
The models.py im working on is:
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
city = models.CharField(max_length=120, default="Add your city")
country = models.CharField(max_length=120, default="Add your country") #(max_length=2, choices=[(x[0], x[3]) for x in country.COUNTRIES])
zipcode = models.CharField(max_length=8, default="Add your zip/postcode")
birthyear = models.IntegerField(max_length=4, default="Add your birthyear")
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __unicode__(self):
return str(self.user.username)
class Meta:
ordering = ['-updated', '-timestamp']
You don't need to pass the model class to the method.
profile = UserProfile.objects.get_or_create(UserProfile, user=user)
should be
profile, created = UserProfile.objects.get_or_create(user=user)