Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
123 views
in Technique[技术] by (71.8m points)

python - Django find object with 2 matching fields in for loop

I have an array of Product Object id’s: ['ypxiQsnL4Etm', 'eWGzBlgcBy5l', 'ki5H4U4unB2v']

And I have a 'Deal' object that has 2 fields with product 1 and 2.

class Deal(models.Model):
    name = models.CharField(max_length=50, null=True)
    product1 = models.ForeignKey(Product, on_delete=models.CASCADE, blank=True, null=True,
                                 related_name='product1_product')
    product2 = models.ForeignKey(Product, on_delete=models.CASCADE, blank=True, null=True,
                                 related_name='product2_product')

I want to loop through that array and see which of those arrays are in the same Deal object. If one of those id’s are in the same object, that is a match. After the match is found, delete the id`s that matched from the array.

I tried the following:

for i in cart:
    try:
        product = Product.objects.get(product_id=i)
        if product.deal_type:
            product_id = product.product_id
            combi_products.append(product_id)
            print(combi_products)

    except:
        pass

length = len(combi_products)
if length > 1:
     # Possible solution from markwalker - third try
     # match = Deal.objects.filter(Q(product1__product_id__in=combi_products) | Q(product2__product_id__in=combi_products))
        # if match:
        #     print('test', match)
    for cp in combi_products:
        try:
            deal_1 = Deal.objects.get(product1__product_id=cp)
            if deal_1:
                try:
                    print(cp)
                    # My try
                    #matched_through = Deal.objects.get(product1__product_id=deal_1.product1.product_id, product2__product_id=cp)
                    #print(matched_through)

                    # Possible solution from AjayLingayat - second try
                     #matched_through = Deal.objects.get(product1__product_id=cp, product2__product_id=cp)
                     #print(matched_through)
                except:
                    pass
        except:
            pass

Example of a matched Deal object with the product object ID`s from the array:

# The array
combi_products = ['ypxiQsnL4Etm', 'eWGzBlgcBy5l', 'ki5H4U4unB2v']

# Match
Deal.object.get(product1__product_id='ypxiQsnL4Etm', product2__product_id='ki5H4U4unB2v')

# array after match
combi_products.remove('ypxiQsnL4Etm')
combi_products.remove('ki5H4U4unB2v')
combi_products = ['eWGzBlgcBy5l']

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Ok, so assuming you've got a list of possible Product object IDs and you want to match to Deal objects, I'd recommend Q objects.

from django.db.models import Q

product_ids = ['ypxiQsnL4Etm', 'eWGzBlgcBy5l', 'ki5H4U4unB2v']


deals = Deal.objects.filter(
    Q(product1.product_id__in=product_ids) | Q(product2.product_id__in=product_ids)
)

The | used with Q objects does an OR in SQL. And then using __in through the ORM lets you pass a list so you don't have to iterate it yourself.

This will avoid doing get and the broad try/except blocks.

If you only want 1 Deal from the query, then just take the first object;

deals = Deal.objects.filter(
    Q(product1.product_id__in=product_ids) | Q(product2.product_id__in=product_ids)
)

deal = deals.first()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
...