贝宝服务器集成问题

时间:2020-10-25 01:22:07

标签: python django paypal

我在创建网络即时消息时遇到了一些问题。付费了,多数民众赞成在正常工作,我的问题是只有一行代码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})

在shopping_购物车中,型号为:

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)

好,使用thats模型并遵循很多paypal教程(由于官方文档对我来说不是很清楚),我在paypal应用程序中进行了查看,这是问题所在:

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中的curso: #request.user.UserProfile.cursos.add(curso))将其添加到UserProfile中。

请帮助我!

编辑: 控制台完全错误(有一些额外的prints()):

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

1 个答案:

答案 0 :(得分:0)

错误消息非常清楚。您也可以轻松地用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