【问题标题】:Django Models: Many to Many or One to ManyDjango 模型:多对多或一对多
【发布时间】:2019-09-15 16:19:06
【问题描述】:

我试图弄清楚如何适当地创建 Order 和 Ticket 模型之间的关系。用户可以购买多张门票,并且会收到一个门票 ID——但是当用户支付门票数量(或门票 ID)时——我希望它显示带有门票 ID# 的订单 ID#。但是,我不确定如何创建 Ticket 和 Order 模型之间的关系。我什至需要 Order 才能加入 Ticket 模型吗?你有什么建议?我尝试使用 Order as many-to-many 与票的关系,但它似乎没有用。建议会有所帮助。

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")-----THIS HAS BEEN DELETED
    created_at=models.DateTimeField(auto_now_add=True)
    updated_at=models.DateTimeField(auto_now=True)
    ```

【问题讨论】:

  • 听起来你还在搞清楚,你到底想在你的数据库中表示什么。一旦你找到了一个坚实的目标,解决方案可能只是“点击”。我似乎不清楚的问题:购买的机票总是订单的一部分吗?用户是否在购买票证、票证、订单或订单?
  • @Bloodmallet:感谢您的回复。我制作了用户在会话中的顺序,他/她选择了他们想要的票数,然后必须为此付费,所以我认为 Order 模型适合与票证 ID 连接?需要一个订单模型来连接 Ticket ID 吗?
  • 请注意,您不得这样定义您自己的用户模型。使用内置的,它会为您处理散列和检查密码。 (如果您将 AbstractUser 子类化,则可以定义您自己的,但在您的情况下似乎没有任何意义。)
  • 听起来您希望用户始终获得订单。一个订单持有选定的工单。一个用户可以有多个订单。但是一个订单只能有一个所有者用户。一个订单可以有多个工单。一张票只能有一个订单。听起来用户不需要任何特殊字段。订单需要用户的外键。 Ticket 需要一个 ForeignKey 才能订购。这样所有提到的限制都到位。但请记住,如果您不小心,这种方式可能会出现空订单(没有票的订单)。

标签: django model many-to-many


【解决方案1】:

按顺序,我建议使用带有用户的 ForeignKey 以及带有 Ticket 的 ForeignKey。一位用户可能有多个工单和多个订单。一个订单可能有多个票。

【讨论】:

  • 对于每个订单的多张门票,您需要一个 FK 才能在门票中订购,而不是相反。
  • 感谢 cwhisperer 的回复。基本上,订单模型将在用户之后出现,而是作为“购买者”作为外键。票证有一个外键与订单?
  • Ticket 有一个带有 Order 的外键?凭票订购
【解决方案2】:

有多种可能性,具体取决于您以后要如何处理此订单。

如果订单是基于票的(每售出一张订单):

  1. Ticket 和 Order 需要有 OneToOne 关系:每张票 只会导致一个订单,一个订单会导致一张票。
  2. 因此您可以过滤特定用户购买的所有门票并 检索订单,然后为每张票访问订单:

相关代码:

user_tickets = Ticket.objects.filter(purchaser='a scpecific user_id')
for ticket in user_tickets:
     print(ticket.order.id)

如果订单是基于客户端的(一个订单链接到一个用户并包含多个票证),那么您应该将 ForeignKey 添加到 User in Order 和 ForeignKey to Order 在票证中:

class Order(models.Model):
    ...
    buyer=models.ForeignKey(User, related_name="bought_tickets")
    ...
class Ticket(models.Model):
    purchaser = models.ForeignKey(User, related_name="purchases", on_delete=models.PROTECT)
    order = models.ForeignKey(Order)
    ...

【讨论】:

  • 感谢 Ben 的澄清!我添加/迁移了您描述的上述模型。我还添加了: order=models.ForeignKey(Order, related_name="orders", on_delete=models.PROTECT) 到 Ticket 模型。我正在尝试将 Ticket ID 与 Order ID 一起使用,因此我声明当 request.session 中的用户提交票证选项时,它将在后台获取订单 ID,直到用户提交订单后,我将显示订单ID。但是,我遇到了一个错误,即 Name Error: 'order_id' not defined。
  • def add(request): if not 'user_id' in request.session: return redirect('/chrisgrafil') if request.method!='POST': messages.error(request, 'Please select the following options') return redirect('/dashboard') else: Ticket.objects.create(venue=request.POST['venue'], quantity=request.POST['quantity'], loop=request.POST['loop'], purchaser=User.objects.get(id=request.session['user_id']), order=Order.objects.get(id=order_id)) return redirect ('/confirmation')
猜你喜欢
  • 2023-04-06
  • 2020-05-04
  • 2017-05-15
  • 2011-01-03
  • 2016-07-17
  • 2012-03-24
  • 1970-01-01
  • 2014-05-16
  • 2011-12-20
相关资源
最近更新 更多