【问题标题】:Problems with paypal server integration贝宝服务器集成问题
【发布时间】:2021-02-07 16:03:52
【问题描述】:

我在创建网络即时消息时遇到了一些问题。付款已完成,一切正常,我的问题是只有一行代码 XD。 我试图在帐单中“保存”购买的产品的名称(在这种情况下是用于课程),然后将该课程传递给用户个人资料,以便他可以访问该课程。 我是 python 和 django 的新手,我知道该怎么做。

首先是我在项目中的组织的重要简历:

myApp  _ apps ______content
      |       |
      |       |_____shopping_cart
      |
      |
      |_ paypal
      |
      |_ user

好的,所以我的内容模型是:

class Course(models.Model):
    name = models.CharField(max_length=100)
    slug = models.SlugField(unique=True)
    thumbnail = models.ImageField(upload_to="courseThumbnails/")
    publish_date = models.DateTimeField(auto_now_add=True)
    last_update = models.DateTimeField(auto_now=True)
    description = models.TextField()
    price = models.FloatField()
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    #agregar despues un field de recursos para descargar material nose si aca o en video mejor

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse("content_app:course-detail", kwargs={"slug":self.slug})

在购物车中的模型是:

from django.conf import settings
from django.db.models import Sum
from django.db import models
from apps.content.models import Course
# Create your models here.
 
class OrderItem(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE)

    def __str__(self):
        return self.course.name

class Order(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete= models.CASCADE)
    is_ordered = models.BooleanField(default=False)
    items = models.ManyToManyField(OrderItem)
    ref_code = models.CharField(max_length=50)

    def __str__(self):
        return self.user.username

    
    def get_total(self):
        return self.items.all().aggregate(order_total=Sum('course__price'))['order_total']

我在贝宝中的模型是:

from django.db import models
from apps.shopping_cart.models import Order
from apps.content.models import Course, 

class Compra(models.Model):
    id = models.CharField(primary_key= True, max_length=100)
    estado = models.CharField(max_length=100)
    codigo_estado = models.CharField(max_length=100)
    cursos = models.ManyToManyField(to=Order, related_name='comprado')
    total_de_la_compra = models.DecimalField(max_digits=5 ,decimal_places= 2)
    nombre_cliente = models.CharField(max_length=100)
    apellido_cliente = models.CharField(max_length=100)
    correo_cliente = models.EmailField(max_length=100)
    direccion_cliente = models.CharField(max_length=100)

    class Meta:
        verbose_name = 'Facturacion'
        verbose_name_plural= 'Facturaciones'

    def __str__(self):
        return str(self.nombre_cliente)


class Payment(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    total_amount = models.FloatField()
    date_paid = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.order.user)

最后一个模型是给用户的:

from django.db import models
from django.conf import settings
from django.db.models.signals import post_save
from apps.content.models import Course, 

class UserProfile(models.Model):
    cursos = models.ManyToManyField(Course, blank=True)
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

    def __str__(self):
        return self.user.username

    def cursos_list(self):
        return self.cursos.all()


def post_user_signup_receiver(sender, instance, created, *args, **kwargs):
    if created:
        UserProfile.objects.get_or_create(user=instance)
post_save.connect(post_user_signup_receiver, sender=settings.AUTH_USER_MODEL)

使用该模型并遵循许多贝宝教程(因为官方文档对我来说不够清楚)我在贝宝应用程序中进行了查看,这就是问题所在:

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, JsonResponse
from paypalcheckoutsdk.core import PayPalHttpClient, SandboxEnvironment
from paypalcheckoutsdk.orders import OrdersGetRequest, OrdersCaptureRequest
from apps.shopping_cart.models import Order
from user.models import UserProfile
from .models import Compra, Payment

import sys, json


def pago(request):
    order = get_object_or_404(Order, user=request.user)
    payment = Payment()
    payment.order = order
    payment.total_amount = float(order.get_total())
    payment.save()
    print('payment:' + str(payment.total_amount))
   
    data = json.loads(request.body)
    order_id = data['orderID']
    print('order_id: ' + order_id)

    detalle = GetOrder().get_order(order_id) 
    detalle_precio = float(detalle.result.purchase_units[0].amount.value)
   
    if detalle_precio == payment.total_amount:
        trx = CaptureOrder().capture_order(order_id, debug=True)
        print('transaccion: ' + trx.result.id)
       
        pedido = Compra(
            id= trx.result.id,
            estado= trx.result.status,
            codigo_estado= trx.status_code,

            #HERE IS MY PROBLEM
     ---->  **cursos= Order.items.all(),**   <----
     
            total_de_la_compra = trx.result.purchase_units[0].payments.captures[0].amount.value,
            nombre_cliente= trx.result.payer.name.given_name,
            apellido_cliente= trx.result.payer.name.surname,
            correo_cliente= trx.result.payer.email_address,
            direccion_cliente= trx.result.purchase_units[0].shipping.address.address_line_1)
        pedido.save() #guardamos en base de datos la info de la Transaccion
        #la funcion json en el html esta pidiendo una respuesta por lo q se le pasa esta variable data:
        data = {
            "id": f"{trx.result.id}",
            "nombre_cliente": f"{trx.result.payer.name.given_name}",
            "mensaje": "Ahora ya puedes acceder al contenido! =D"
        }
        return JsonResponse(data)
    else:
        data = {
            "mensaje": "Error =( "
        }
        return JsonResponse(data)

如果我使用 def pago(request) 中的表达式: ... cursos = Order.items.all() 它打印: TypeError: 禁止直接分配到多对多集合的前端。请改用 cursos.set()。

以及我无法帮助我在 def pago(request) 中查看 OrderItems 课程名称的所有其他选项。我想让这个“出价”。然后将它与某种 for 一起使用(例如:for curso in cursos: # request.user.UserProfile.cursos.add(curso)) 将其添加到 UserProfile 中。

请帮助我!!

编辑: 控制台中的完整错误(有一些额外的打印()):

System check identified no issues (0 silenced).
October 25, 2020 - 01:10:01
Django version 3.1.2, using settings 'AutismoCDV.settings.local'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[25/Oct/2020 01:10:04] "GET /order-summary/ HTTP/1.1" 200 10001
payment:35.0
order_id: 504320196R962682N
detalle_precio: 35.0
Status Code:  201
Status:  COMPLETED
Order ID:  504320196R962682N
Links: 
    self: https://api.sandbox.paypal.com/v2/checkout/orders/504320196R962682N   Call Type: GET
Capture Ids: 
     9F055159V4840413P
Buyer:
transaccion: 504320196R962682N
Internal Server Error: /pago/
Traceback (most recent call last):
  File "/home/yeti/Documentos/PROG/partesONG/10.03agregaraprofile/env/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/home/yeti/Documentos/PROG/partesONG/10.03agregaraprofile/env/lib/python3.8/site-packages/django/core/handlers/base.py", line 179, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/yeti/Documentos/PROG/partesONG/10.03agregaraprofile/AutismoCDV/paypal/views.py", line 45, in pago
    pedido = Compra(
  File "/home/yeti/Documentos/PROG/partesONG/10.03agregaraprofile/env/lib/python3.8/site-packages/django/db/models/base.py", line 496, in __init__
    _setattr(self, prop, kwargs[prop])
  File "/home/yeti/Documentos/PROG/partesONG/10.03agregaraprofile/env/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py", line 545, in __set__
    raise TypeError(
TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use cursos.set() instead.
[25/Oct/2020 01:10:29] "POST /pago/ HTTP/1.1" 500 78941

【问题讨论】:

  • 请将完整的错误回溯添加到您的问题中。
  • 添加了完整的错误
  • 您可以将项目添加到多对多关系中,前提是您要添加的对象已保存。从构造函数中移除赋值,添加到save()之后。
  • 感谢您的快速响应。我不太明白你的意思,你是说从函数“pago”中获取 order.items.all() 然后使用 save()?如果不是这样,你能在函数中告诉我该怎么做吗?谢谢

标签: python django paypal


【解决方案1】:

错误信息非常清楚。您也可以轻松地通过 Google 搜索解决方案。

我相信你需要做的就是删除行

cursos= Order.items.all()

并添加

cursos.set(Order.objects.all())

在您保存对象的行之后。我认为您真正想要做的是仅与您正在保存的一个订单建立关系,这将按如下方式完成:

cursos.set(Order.objects.filter(id=order_id))

这里也解释了同样问题的答案:

Direct assignment to the forward side of a many-to-many set is prohibited. Use emails_for_help.set() instead

【讨论】:

    猜你喜欢
    • 2018-02-02
    • 2017-10-26
    • 2021-08-11
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 2015-01-01
    • 2012-05-21
    • 2020-06-26
    相关资源
    最近更新 更多