Yousef
Yousef

Reputation: 139

Django group options list

Using Django, I have the following working example to make a list with group option:

self.fields["crop"].choices = [( "First", ( ('1','aaa'), ('2','bbb'), ) ), ( "Second", ( ('3','ccc'), ) ), ]

First Method: I tried to make it dynamic using the hard way:

    sub_item =''
    grouped_items=''

    for k in Field.objects.filter(farm=farm):
      print (k.field_name )
      for o in Crop.objects.filter(farming_year=farming_year, field=k ): 
        sub_item = sub_item + '('+ str(o.id) + ',"' +o.crop_name  + '"),'
      grouped_items= grouped_items + '("' + k.field_name + '", (' + sub_item + ')),'
      sub_item=''
    full_list_items= '[' + grouped_items + ']'
    print (full_list_items)  
    self.fields["crop"].choices = full_list_items
    print(full_list_items )

I always get the following error: not enough values to unpack (expected 2, got 1)

Second method: To test my code I copied the print(full_list_items )'s results from the terminal and assigned it directly to the crop list as shown below, and it works again!!!

self.fields["crop"].choices = [( "First", ( ('1','aaa'), ('2','bbb'), ) ), ( "Second", ( ('3','ccc'), ) ), ] 

the question here why I cannot get the required results when I use the first method and I did when I use the second one!!

Upvotes: 1

Views: 78

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599778

You're building up a single string, not a list of tuples. I don't know why you are doing that. Instead of all this string concatenation, you should keep things as Python data structures:

grouped_items = []
for k in Field.objects.filter(farm=farm):
  sub_item = []
  for o in Crop.objects.filter(farming_year=farming_year, field=k): 
    sub_item.append((str(o.id), o.crop_name))
  grouped_items.append((k.field_name, sub_item))
self.fields["crop"].choices = grouped_items

Note that the inner loop could be rewritten as a list comprehension, and simplified further by using the reverse relation:

sub_item = [(str(o.id), o.crop_name) for o in k.crop_set.filter(farming_year = farming_year)]

Upvotes: 1

Related Questions