panosdotk
panosdotk

Reputation: 27

Django show all objects and foreach object all compatible objects

I am new to Django and I want to create a compatibility model for mobile phone. I create a model with all phone details like name, screen size etc. and I thought of creating a new model for compatibility.

The first model in Django

class MobilePhone(models.Model):
    name = models.CharField(max_length=500)
    manufacturer = models.ForeignKey(MobileManufacturer, on_delete=models.PROTECT)
    dimensions = models.TextField(max_length=500, null=True, blank=True)
    display_type = models.CharField(max_length=500, null=True, blank=True)
    display_size = models.CharField(max_length=500, null=True, blank=True)

and another model for compatibility

class Compatibility(models.Model):
    comp_id = models.CharField(max_length=30)
    comp_type = models.CharField(max_length=30)
    mobile_id = models.ForeignKey('MobilePhone', on_delete=models.CASCADE)

I fill the MobilePhone table with values

id name manufacturer dimensions
1 Phone 1 Samsung 8x15
2 Phone 2 Samsung 8x15
3 Phone 3 Samsung 8x15
4 Phone 4 Samsung 8x15

and the Compatibility table with

id comp_id comp_type mobile_id
1 100 screen 1
2 100 screen 2
3 101 screen 3
4 100 screen 4

the comp_id is the unique number I use to group the phones

now with

all_entries = MobilePhone.objects.all()

get all mobile phones like

- Phone 1
- Phone 2
- Phone 3
- Phone 4

what I want is

- Phone 1
-- (same with Phone 2, Phone 4)

- Phone 2
-- (same with Phone 1, Phone 4)

- Phone 3
-- (no compatibility)

- Phone 4
-- (same with Phone 1, Phone 2)

I do not know if my thinking is correct. I may be wrong in the way I design the model or if there is a simpler way. I would appreciate any help or advice

Upvotes: 1

Views: 422

Answers (1)

Alexandr Tatarinov
Alexandr Tatarinov

Reputation: 4044

It should not be a problem to make a nested for loop. I would use print() for simplicity, but the same can be applied to the Django templating system.

for mobile in MobilePhone.objects.all():
    print('-', mobile.name)
    compatibles = list(mobile.compatibility_set.all())
    if not compatibles:
        print('(no compatibility)')
    else:
        comp_list = ', '.join((c.name for c in compatibles))
        print(f'-- (same with {comp_list})')

Okay, I've cheated a bit, since you cannot use list comprehensions in the template. However, you could extract the comp_list to the method in the Mobile model and use that in the template. Or create a template tag (there is already one), or make the computations in the view and provide a list of tuples to the template, you choose.

Upvotes: 1

Related Questions