Chau Loi
Chau Loi

Reputation: 1225

How to set up ManyToOneRel in Django Models

I have 2 tables Voucher (with all information of a voucher) and VoucherCustomer (listing number of vouchers that a user has used)

Here is my model:

class Voucher(models.Model):
    code = models.ForeignKey('VoucherCustomer', related_name= 'voucher_code', on_delete = models.CASCADE)  (1)
    start_at = models.DateTimeField()                                                                      (2)
    end_at = models.DateTimeField()                                                                        (3)
    usage_limit_per_customer = models.BigIntegerField()                                                    (4)
    times_used = models.BigIntegerField()                                                                  (5)                                                                           
    usage_limit_daily = models.BigIntegerField()                                                           (6)
    times_used_daily = models.BigIntegerField()                                                            (7)
    is_global = models.BooleanField(blank=True, null=True)                                                 (8)
    is_active = models.BooleanField()                                                                      (9)

class VoucherCustomer(models.Model):
    voucher_code = models.ManyToOneRel(field = "voucher_code", field_name = "voucher_code", to = "code")(1)
    customer_id = models.IntegerField()                                                                    (2)
    times_used = models.BigIntegerField(blank=True, null=True)                                             (3)
    created_at = models.DateTimeField(blank=True, null=True)                                               (4)
    updated_at = models.DateTimeField(blank=True, null=True)                                               (5)

Here is the sample data:

+++++++ Voucher ++++++++
 (1)             (2)                   (3)           (4)   (5)    (6)   (7)   (8)    (9)
TEST01 | 2020-11-30 17:00:00 | 2021-03-01 16:59:59 | 100 | 1124 | 5000 | 6 | true | true

+++++++ VoucherCustomer ++++++++
(1)     (2)    (3)            (4)                         (5)   
TEST01 10878    9   2020-12-03 02:17:32.012722  2020-12-08 10:32:03.877349
TEST01 12577    1   2020-12-02 07:17:34.005964  2020-12-02 07:17:34.005964
TEST01 8324    18   2020-12-02 07:49:37.385682  2021-02-01 14:35:38.096381
TEST01 7638     2   2020-12-02 08:17:46.532566  2020-12-02 08:17:46.532566
TEST01 3589     1   2020-12-02 14:57:01.356616  2020-12-02 14:57:01.356616

I am not quite sure about how and what to put in parameters of models.ManyToOneRel of Django.

when I run this code:

query = Voucher.objects.filter(
            start_at__lte = now,
            end_at__gte = now,
            is_active = True,
            times_used__lt = F('usage_limit'),
            times_used_daily__lt = F('usage_limit_daily'),
            VoucherCustomer__customer_id = customer
            ).annotate(
                usage_so_far=Coalesce('VoucherCustomer__times_used', Value(0))
            ).filter(
                usage_so_far__gte=F('usage_limit_per_customer')
            ).order_by('created_at').values()

I got this error:

Cannot resolve keyword 'VoucherCustomer' into field. Choices are: code, start_at...

Upvotes: 0

Views: 3480

Answers (1)

sin tribu
sin tribu

Reputation: 1180

According to this question from 2013 models.ManyToOneRel is only used within django and is not part of the api. Difference between ManyToOneRel and ForeignKey?

Since you have the customer you can get all the Vouchers associated with that customer with something like

query = customer.voucher_set.filter(             
            start_at__lte = now,
            end_at__gte = now,
            is_active = True,
            times_used__lt = F('usage_limit'),
            times_used_daily__lt = F('usage_limit_daily'),
  
            ).annotate(
                usage_so_far=Coalesce('VoucherCustomer__times_used', Value(0))
            ).filter(
                usage_so_far__gte=F('usage_limit_per_customer')
            ).order_by('created_at').values()
)

Note I didn't test it and hope I understood your question correctly.

Upvotes: 1

Related Questions