-1

The title may be a little confusing here, so let me explain.

Firstly I have a model of a list of items which is a foreign key of another model. The foreign key object has access wh_item_id and wh_item_name. I am trying to put that information into this format

wh_item_id=wh_item_name

So for example it will return as:

102944=Hands of the Light

Now the part where it gets tricky is that I wish each field in the model to be put into this string, and then into a list that can be accessed later. Minus any blank fields in the model.

The original model:

class ProtectionList(models.Model):
    character = models.ForeignKey(Character)
    main_hand = models.ForeignKey(Loot, related_name="Main Hand", blank=True, null=True)
    off_hand = models.ForeignKey(Loot, related_name="Off Hand", blank=True, null=True)
    head = models.ForeignKey(Loot, related_name="Head", blank=True, null=True)
    neck = models.ForeignKey(Loot, related_name="Neck", blank=True, null=True)
    shoulder = models.ForeignKey(Loot, related_name="Shoulder", blank=True, null=True)
    back = models.ForeignKey(Loot, related_name="Back", blank=True, null=True)
    chest = models.ForeignKey(Loot, related_name="Chest", blank=True, null=True)
    wrist = models.ForeignKey(Loot, related_name="Wrist", blank=True, null=True)
    hands = models.ForeignKey(Loot, related_name="Hands", blank=True, null=True)
    waist = models.ForeignKey(Loot, related_name="Waist", blank=True, null=True)
    legs = models.ForeignKey(Loot, related_name="Legs", blank=True, null=True)
    feet = models.ForeignKey(Loot, related_name="Feet", blank=True, null=True)
    ring1 = models.ForeignKey(Loot, related_name="Ring 1", blank=True, null=True)
    ring2 = models.ForeignKey(Loot, related_name="Ring 2", blank=True, null=True)
    trinket1 = models.ForeignKey(Loot, related_name="Trinket 1", blank=True, null=True)
    trinket2 = models.ForeignKey(Loot, related_name="Trinket 2", blank=True, null=True)

So there could be anything up to 16 items in this list, however I need to remove anything in list that shows as None.

For Example,

main_hand returns an object off_hand returns None head returns an object ... (I'll just use 3 fields for now for simplicity)

I wish the list to look like the following:

item_list = [1234=main hand itemname,5678=head itemname]

Missing out the off_hand.

Loot model for reference

class Loot(models.Model):
    wh_item_id = models.CharField(verbose_name="Wowhead Item ID", max_length=255)
    wh_item_name = models.CharField(verbose_name="Wowhead Item Name", max_length=255)
    gear_type = models.CharField(max_length=255, blank=True, null=True)
    lockout_tier = models.IntegerField(blank=True, null=True) 

EDIT:

What I essentially am after is the following:

item_list = [item_list.main_hand.wh_item_id + '=' + item_list.main_hand.wh_item_name,item_list.off_hand.wh_item_id + '=' + item_list.off_hand.wh_item_name,item_list.head.wh_item_id + '=' + item_list.head.wh_item_name,item_list.neck.wh_item_id + '=' + item_list.neck.wh_item_name,item_list.shoulder.wh_item_id + '=' + item_list.shoulder.wh_item_name,item_list.back.wh_item_id + '=' + item_list.back.wh_item_name,item_list.main_hand.wh_item_id + '=' + item_list.chest.wh_item_name,item_list.main_hand.wh_item_id + '=' + item_list.main_hand.wh_item_name,item_list.main_hand.wh_item_id + '=' + item_list.main_hand.wh_item_name,item_list.main_hand.wh_item_id + '=' + item_list.main_hand.wh_item_name,item_list.main_hand.wh_item_id + '=' + item_list.main_hand.wh_item_name,item_list.main_hand.wh_item_id + '=' + item_list.main_hand.wh_item_name,item_list.main_hand.wh_item_id + '=' + item_list.main_hand.wh_item_name,item_list.main_hand.wh_item_id + '=' + item_list.main_hand.wh_item_name,item_list.main_hand.wh_item_id + '=' + item_list.main_hand.wh_item_name,item_list.main_hand.wh_item_id + '=' + item_list.main_hand.wh_item_name]

But I only want the items that do not return None to be in that list.

Llanilek
  • 3,386
  • 5
  • 39
  • 65

3 Answers3

0

I believe Django has a model_to_dict feature which lets you iterate over the object as you would a dict.

from django.forms.models import model_to_dict

char_dict = model_to_dict(Your_Model_Instance)

You can then iterate over that dict and get what you're looking for in whatever way you prefer to ignore the None values. As an example -

my_list = []
for k, v in char_dict.iteritems():
    if v is not None:
        my_list.append("{}={}".format(k, v))
-1

We have a pretty good format for representing objects (or classes, since Python classes are objects) as strings: JSON. If you don't want to use that, or you find JSON parsers aren't working well for you, note that you can iterate through the properties on a class/object by using class_name.__dict__. So loop through all the key, val pairs in your class and add them to a list as you please. You'd probably want to filter out the ones that start with _.

Example:

class myClass:
    thing1 = 'hello'
    thing2 = 'world'

[key + '=' + str(val) for key, val in myClass.__dict__.iteritems() if key[0] != '_']

gives:

['thing2=world', 'thing1=hello']
Mike Bell
  • 1,356
  • 11
  • 9
  • I started thinking this way too. Be careful with this, since the `character` field will also show up on your list, better to do `if type(key[1])==Loot` which also ditches `None`s. – AMADANON Inc. Mar 24 '14 at 01:29
  • Yea I'm unfamiliar with the details of whatever ORM that is (I haven't used django much), so surely there would have to be a bit more logic in the filtering/mapping. – Mike Bell Mar 24 '14 at 01:34
  • This doesn't really answer my question. Although it's given me a better understanding. The object is from a model, main_hand, off_hand etc is the foreign key of another model which has in it (not limited to) wh_item_id and wh_item_name. doing the above with the model object just returns the first field in the model which isn't what I'm after. – Llanilek Mar 24 '14 at 15:40
  • Anyone care to elaborate on down-votes? Or someone just having a bad day? – Mike Bell Mar 26 '14 at 16:40
-1

You might also consider normalizing your data properly - create a "body-location" table, which contains "Main hand", "Off hand" etc (which never changes), and then create a "person-body-location", which has character, a body location, and a loot. You can make the person-body-location unique on combined person and body-location as shown in How to define two fields "unique" as couple to ensure one character only has one "Main hand" etc.

Community
  • 1
  • 1
AMADANON Inc.
  • 5,753
  • 21
  • 31