ORM Django Много ко многим - PullRequest
       16

ORM Django Много ко многим

0 голосов
/ 18 апреля 2019

Я пытаюсь получить ОДИН идентификатор заказа для билетов, приобретенных пользователем. Когда я ставлю Order.objects.all(), он показывает все идентификаторы заказа из базы данных, но я пытаюсь получить только один order ID. Когда я вместо этого запрашиваю: Order.objects.filter(buyer=Ticket.objects.get(id='tic_id')) ----, это выдает мне ошибку:

недопустимый литерал для int () с основанием 10: 'tic_id'.

Может кто-нибудь проверить, верны ли мои модели и как запросить, чтобы получить только один order ID, а не все order ID s? Например, в настоящее время он показывает:

"Ваш номер заказа 123456789101112131415", и я нацеливаю его на отображение "номер заказа 11"; Спасибо, я ценю ваше терпение!

models.py

class User(models.Model):
    first_name=models.CharField(max_length=100)
    last_name=models.CharField(max_length=100)
    email=models.CharField(max_length=100)
    password=models.CharField(max_length=100)
    created_at=models.DateTimeField(auto_now_add=True)
    updated_at=models.DateTimeField(auto_now=True)

class Ticket(models.Model):
    venue=models.CharField(max_length=100)
    quantity=models.PositiveIntegerField()
    price=models.DecimalField(default=25.00, max_digits=5, decimal_places=2, null=True, blank=True)
    loop=models.CharField(max_length=100)
    purchaser = models.ForeignKey(User, related_name="purchases", on_delete=models.PROTECT)
    created_at=models.DateTimeField(auto_now_add=True)
    updated_at=models.DateTimeField(auto_now=True)

class Order(models.Model):
    full_name=models.CharField(max_length=100)
    cc_number=models.PositiveIntegerField()
    exp_date=models.PositiveIntegerField()
    cvc=models.PositiveIntegerField()
    buyers=models.ManyToManyField(Ticket, related_name="bought_tickets")
    created_at=models.DateTimeField(auto_now_add=True)
    updated_at=models.DateTimeField(auto_now=True)

views.py

def process(request):
Order.objects.create(full_name=request.POST['full_name'], cc_number=request.POST['cc_number'],exp_date=request.POST['exp_date'], cvc=request.POST['cvc'])    
return redirect('/checkout')

def checkout(request):
    context={
        "user":User.objects.get(id=request.session['user_id']),

        "tickets": Ticket.objects.filter(purchaser=User.objects.get(id=request.session['user_id'])).annotate(total=Sum(F('quantity') * F('price'),  output_field=FloatField())).annotate(tax=ExpressionWrapper(F('quantity') * F('price')*0.0725,  output_field=FloatField())).annotate(total_price=ExpressionWrapper(F('quantity') * F('price') + F('tax'),  output_field=FloatField())),

        "order":Order.objects.filter(buyer=Ticket.objects.get(id='tic_id'))
    }
    return render(request, 'first_app/checkout.html', context)

checkout.html

<p class="lead">Your order number is:<strong>{% for o in order %}{{o.id}}{% endfor %}</strong><p class="lead">with ticket number:</p><strong>{% for ticket in tickets %}{{ticket.id}}{% endfor %}</strong>

Ответы [ 2 ]

0 голосов
/ 19 апреля 2019

Я чувствую, что отношения в вашей схеме немного нарушены. Сейчас: enter image description here

Что должно быть:
enter image description here

Затем вы получите идентификатор заказа с помощью Order.objects.get(buyer=user_id).values_list('pk', flat = True)[0] (НЕПРАВИЛЬНО: см. Обновление!), И владелец билета будет указан в заказе, в котором он был куплен.
Если что-то не так, всегда полезно взять ручку и бумагу и начать рисовать некоторые диаграммы.


UPDATE: Модели будут выглядеть примерно так:

class Order:
    # one order can only have one buyer, but Users may have many orders
    buyer = ForeignKey(User, related_name = 'orders') 

class Ticket:
    # one ticket can only have one order, but many tickets may be ordered at once
    order = ForeignKey(Order, related_name = 'tickets')

    def get_owner(self):
        # Returns the user that has ordered this ticket.          
        return self.order.buyer

Также я только что понял, что вы все равно не получите ни одного заказа от Order.objects.get(buyer=user_id), поскольку у пользователя может быть более одного заказа. Одним из подходов будет перенаправление на URL, содержащий созданный заказ, или сохранение этого заказа в сеансе. Или просто:

def process(request):
    order = # ... create order
    context = {'order': order, # ... other stuff }
    return render(request, 'first_app/checkout.html', context)
0 голосов
/ 18 апреля 2019

Вы передаете str параметру id Ticket.objects.get(id='tic_id').Я полагаю, что tic_id является переменной, поэтому вам нужно использовать ее без кавычек Ticket.objects.get(id=tic_id)

...