I use stripe Api Payment method and I have a boolean filed in my database called ordered set to False
I just want it to be True after payment
Here is my views.py:
class OrderSummary(LoginRequiredMixin, View):
def post(self, request, *args, **kwargs):
order = Order.objects.get(user=self.request.user) #this is to bring the order
delivered = order.ordered
YOUR_DOMAIN = "http://127.0.0.1:8000"
checkout_session = stripe.checkout.Session.create(
payment_method_types=['card'],
metadata={
"order_id":order.id,
"order":order,
"delivered":delivered
},
mode='payment',
success_url=YOUR_DOMAIN + "/",
cancel_url=YOUR_DOMAIN + "/",
)
return JsonResponse({'id': checkout_session.id})
And here is after payment webhook views:
#csrf_exempt
def stripe_webhook(request):
payload = request.body
sig_header = request.META['HTTP_STRIPE_SIGNATURE']
event = None
try:
event = stripe.Webhook.construct_event(
payload, sig_header, endpoint_secret
)
except ValueError as e:
# Invalid payload
return HttpResponse(status=400)
except stripe.error.SignatureVerificationError as e:
# Invalid signature
return HttpResponse(status=400)
if event['type'] == 'checkout.session.completed': #this is to bring the order
session = event['data']['object']
customer_email = session["customer_details"]["email"]
orders =session["metadata"]["delivered"]
orders=True
orders.save()
print(session)
# Passed signature verification
return HttpResponse(status=200)
but I got this error
AttributeError: 'bool' object has no attribute 'save'
You are calling save on a variable which is not your model object.
Try:
Order= OrderSummary.Objects.get(id=id)
Order.Ordered=True
Order.save()
This is because you can not .save() a variable (orders here) , you must .save() the model, so you must retrieve the Order object and set its ordered to True and then .save() the Order object.
Related
So I am trying to loop through the list of classes see if there is a match or not
if there is a match return a Response and say there is a match
otherwise register the student
I am using django and django-restframework
Here is my code
#api_view(['POST'])
#permission_classes([IsAuthenticated,])
def createOrderForOnlineClasses(request):
user = request.user
data = request.data
Class = OnlineClass.objects.get(id= data["classId"])
orderCred = {
'pin' : 'SOME_PIN',
'amount' : int(Class.totalPrice),
'callback' : 'http://localhost:3000/verify/',
}
for i in user.userprofile.onlineClass.all():
if i.id == Class.id:
return Response({"details": "Already registered"}, status=status.HTTP_400_BAD_REQUEST)
try:
response = requests.post("https://panel.aqayepardakht.ir/api/create", data=orderCred)
if response.status_code == 200 and not response.text.replace('-',"").isdigit():
# url ='https://panel.aqayepardakht.ir/startpay/'+response.text
registeredClass = RegisterStudentForOnlineClass.objects.create(
user=user,
totalPrice = int(Class.totalPrice),
transId = response.text,
onlineClassName= Class
)
serializer = RegisterForClassSerializer(registeredClass , many=False)
print(serializer.data)
return Response(serializer.data)
else:
return Response({"details": "Error"} , status= status.HTTP_400_BAD_REQUEST)
except Exception as e:
return Response({"details": f"{e}"})
return Response({"details":f"{Class}"}, status=status.HTTP_400_BAD_REQUEST)
So the problem is the function call the
return Response({"details":f"{Class}"}, status=status.HTTP_400_BAD_REQUEST)
first and the rest wont work
Thank you :)
So I Have found the answer the thing is all you have to do is first check if the
len(user.userporfile.onlineClass.all()) == 0
If it is do the rest
else run the for loop
I am trying to create a online class and want to loop through the list of the classes to see if he/she been registered or not
problem is if the list be empty it will return an error
I am using django and django-restframework
here is my code
#api_view(['POST'])
#permission_classes([IsAuthenticated,])
def createOrderForOnlineClasses(request):
user = request.user
data = request.data
Class = OnlineClass.objects.get(id= data["classId"])
orderCred = {
'pin' : 'somepin',
'amount' : int(Class.totalPrice),
'callback' : 'http://localhost:3000/verify/',
}
for i in user.userprofile.onlineClass.all():
if i == Class:
return Response({"details": "allready registered"}, status=status.HTTP_400_BAD_REQUEST)
else:
try:
response = requests.post("URL_TO_SOMEWHERE", data=orderCred)
if response.status_code == 200 and not response.text.replace('-',"").isdigit():
registeredClass = RegisterStudentForOnlineClass.objects.create(
user=user,
totalPrice = int(Class.totalPrice),
transId = response.text,
onlineClassName= Class
)
serializer = RegisterForClassSerializer(registeredClass , many=False)
return Response(serializer.data)
else:
return Response({"details": ""} , status= status.HTTP_400_BAD_REQUEST)
except Exception as e:
return Response({"details": e})
here is the returned error
Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be returned from the view, but received a `<class 'NoneType'>`
Thank you :)
when you call for i in user.userprofile.onlineClass.all() and it is empty it will simply pass the loop. Your problem is actually that you just need a default response for the scenario that user.userprofile.onlineClass.all() is empty.
Simply put a default expected response after the for loop
Docs says only mapping of GET
user_list = UserViewSet.as_view({'get': 'list'})
user_detail = UserViewSet.as_view({'get': 'retrieve'})
tests.py:
def test_admin_can_create_role(userprofiles, aoo_admin, bug_manager, note_admin):
aoo = User.objects.get(username='aoo')
factory = APIRequestFactory()
view = RoleViewSet.as_view()
url = reverse('api:role-list')
data = {
'name': 'FirstAdmin',
'type': Role.RoleType.admin,
'company': 1,
}
request = factory.post(url, data=data, format='json')
force_authenticate(request, user=aoo)
response = view(request)
assert 201 == response.data
viewsets.py
class RoleViewSetPermission(permissions.BasePermission):
message = 'Only Manager or Admin are allowed'
def has_permission(self, request, view):
user = request.user
return user.has_perm('roles.add_role') \
and user.has_perm('roles.change_role') \
and user.has_perm('roles.delete_role')
class RoleViewSet(viewsets.ModelViewSet):
permission_classes = (RoleViewSetPermission,)
queryset = Role.objects.all()
serializer_class = RoleSerializer
filter_backends = (filters.DjangoFilterBackend, SearchFilter)
filter_class = RoleFilter
search_fields = ('name', 'description', 'user__username', 'company__name', 'company__name_th')
def filter_queryset(self, queryset):
try:
company = self.request.user.user_profile.companyappid.company
except AttributeError:
logger.error(f'{self.request.user} has AttributeError')
return Role.objects.none()
else:
logger.info(f'{self.request.user} is {company} member')
return queryset.filter(company=company)
Trackback:
cls = <class 'poinkbackend.apps.roles.api.viewsets.RoleViewSet'>, actions = None, initkwargs = {}
#classonlymethod
def as_view(cls, actions=None, **initkwargs):
"""
Because of the way class based views create a closure around the
instantiated view, we need to totally reimplement `.as_view`,
and slightly modify the view function that is created and returned.
"""
# The suffix initkwarg is reserved for identifying the viewset type
# eg. 'List' or 'Instance'.
cls.suffix = None
# actions must not be empty
if not actions:
> raise TypeError("The `actions` argument must be provided when "
"calling `.as_view()` on a ViewSet. For example "
"`.as_view({'get': 'list'})`")
E TypeError: The `actions` argument must be provided when calling `.as_view()` on a ViewSet. For example `.as_view({'get': 'list'})`
../../.pyenv/versions/3.6.3/envs/poink/lib/python3.6/site-packages/rest_framework/viewsets.py:55: TypeError
Question:
How to do force_authenticate and request.post to the viewsets?
I have no problem with get. It has an answer already in the SO
References:
http://www.django-rest-framework.org/api-guide/viewsets/
I have to use APIClient not APIRequestFactory.
I though it has only one way to do testing.
Here is my example.
def test_admin_can_create_role(userprofiles, aoo_admin, bug_manager, note_admin):
aoo = User.objects.get(username='aoo')
client = APIClient()
client.force_authenticate(user=aoo)
url = reverse('api:role-list')
singh = Company.objects.get(name='Singh')
data = {
'name': 'HairCut',
'type': Role.RoleType.admin,
'company': singh.id, # Must be his companyid. Reason is in the RoleSerializer docstring
}
response = client.post(url, data, format='json')
assert 201 == response.status_code
I am writing an app in django rest-framework:
My views.py:
class tagList(generics.ListCreateAPIView,APIView):
model = tags
serializer_class = getAllTagsDetailSerializer
def get_queryset(self):
print "q1"
print self.request.QUERY_PARAMS.get('tag', None)
print self.request.user
print "q1"
if tags.objects.filter(tag='burger')!= None:
return tags.objects.filter(tag='burger')
else:
content = {'please move along': 'nothing to see here'}
return Response(content, status=status.HTTP_404_NOT_FOUND)
I want to return error status code if query returns None.
But the problem if i try to set Response it throws error:
Exception Type: TypeError
Exception Value:
object of type 'Response' has no len()
Exception Location: /usr/local/lib/python2.7/dist-packages/django/core/paginator.py in _get_count, line 53
Else if query result is Not None it is working.
How can i set status code on Django rest-framework.
The method is expected to return a QuerySet, not a Response object, my bet is that you should throw an Exception, either an APIException or an Http404.
Anyway your handling seems odd, I think you should just return the QuerySet and the framework will handle if the result is empty or not. The method should look like this:
def get_queryset(self):
return tags.objects.filter(tag='burger')
Can you try this
model = tags # Model name
serializer_class = getAllTagsDetailSerializer # Call serializer
def get_queryset(self):
key = self.request.QUERY_PARAMS.get('appKey', None)
getTagName = self.request.QUERY_PARAMS.get('tagName')
keyData = app.objects.filter(appKey=key).exists()
try:
if keyData == True:
return tags.objects.filter(tag=getTagName)
else:
raise exceptions.PermissionDenied
except app.DoesNotExist:
pass
I think it will work....
I'm trying to test the content of messages while processing ModelForms with Django. I've got the following View (assume there's a Thing model with a required name field):
#login_required
def update(request, thing_id):
thing = Thing.objects.get(id=thing_id) # assume this works
if request.method == "POST":
form = ThingModelForm(request.POST, instance=thing)
if form.is_valid():
form.save()
messages.success(request, "Success!")
return redirect("/wherever")
else:
messages.error(request, "Oops!")
else:
form = ThingModelForm(instance=thing)
args = ("myapp/update.html", {"form": form})
kwargs = {"context_instance": RequestContext(request)}
return render_to_response(*args, **kwargs)
Now, I've got two unit tests. The first tests valid data, while the second tests invalid data. (Note that client login happens during setUp):
def test_update_account(self):
url = reverse('update', args=[1]) # assume that's a valid id
resp = self.client.post(url, {"name": "foo"})
self.assertEqual(resp.status_code, 302)
m = resp.cookies.get('messages', '')
self.assertTrue("Success!" in m.output())
And now to test invalid data:
def test_update_account_failure(self):
url = reverse('update', args=[1]) # assume that's a valid id
resp = self.client.post(url, {"name": ""}) # name is required
self.assertEqual(resp.status_code, 200)
# This works:
self.assertTrue("Oops!" in resp.content)
# This fails:
m = resp.cookies.get('messages', '')
self.assertTrue("Oops!" in m.output())
Why would accessing the message's content through the cookie work in one instance but fail in another?
Two things you could check:
When you create the request self.client.post(url, {"name": ""}) is a Thing instance returned here: thing = Thing.objects.get(id=thing_id) If not it will not reach the line of code where you set your error message: messages.error(request, "Oops!") as Thing.objects.get will throw an error.
If there are no results that match the query, get() will raise a
DoesNotExist exception.
If the first thing does return a Thing instance, you could check whether a redirect return redirect("/wherever") after setting the error message messages.error(request, "Oops!") does change anything.