How to pass ForeignKey in dict to create Model object. Django

Viewed 1761

I have created one model to store User name and place

class UserDetails(models.Model):
    name = models.CharField(max_length=50)
    place = models.ForeignKey(City, on_delete=models.CASECADE)

I have one JSON file there I have data of more than 1000 users. like

[
    {"name": "A", "place":1},
    {"name": "B", "place":3},
    {"name": "C", "place":4},
    {"name": "D", "place":1},
    ..
    ..
]

There place field is related to City object id. When I am using below syntax

UserDetails.objects.create(**{"name":"A", "place": 3})

then getting an error, I know instead of passing place id I have to pass obj like:

loc = City.object.get(id=3)
UserDetails.objects.create(**{"name":"A", "place": loc})

This is fine, but I have a large amount of data how can I pass place id or should use bulk_create to save all JSON data in model?

2 Answers

You can use the place_id instead, this is the "twin field" Django creates that is stored in the database, and stores a reference (usually the primarh key) to the target model, given of course such Place already exists:

user_details = [
    UserDetails(name=record['name'], place_id=record['place'])
    for record in list_of_records
]
UserDetails.object.bulk_create(user_details)

Here the list_of_records is thus your list of dictionaries. We can make use of .bulk_create(…) [Django-doc] to add all UserDetails in a small number of insert queries.

This seems to be working:

def model_to_dict_wfk(modelobj):
    opts = modelobj._meta.fields
    modeldict = model_to_dict(modelobj)
    for m in opts:
        if m.is_relation:
            foreignkey = getattr(modelobj, m.name)
            if foreignkey:
                try:
                    modeldict[m.name] = foreignkey
                except:
                    pass
    return modeldict

then use the returned dictionary in the create classmethod

@classmethod
def create(cls, vals):
    obj = cls(**vals)
    obj.save()
    return obj
Related