0👍
I ended up writing a custom save on the model (so that my code doesn’t change, just the model):
def save(self, *args, **kwargs):
try:
super(Car, self).save(*args, **kwargs)
except IntegrityError, e:
existing_object = Car.objects.get(slug=self.slug)
self = existing_object
super(Car, self).save(*args, **kwargs)
return existing_object.id
Now I return the object’s ID to assign it so the save() command looks like this:
the_id = generic_object.save() #e.g. Car
if the_id:
generic_object.id = the_id
2👍
You need get_or_create
:
car,created = Car.objects.get_or_create(slug='car-slug')
if created:
print 'New car was created'
car.slug = 'new-car-slug'
else:
# do whatever needs to be done here
# with the existing car object, which will
# be car
# car.name = 'new name'
car.save()
Whatever arguments you provide to get_or_create
, it will use those to search existing records for the model.
Suppose you don’t know what combination of fields will trigger a duplicate. The easy way is to find out which fields in your model have that restriction (ie unique=True
). You can introspect this information from your model, or a simpler way is to simply pass these fields to get_or_create
.
First step is to create a mapping between your XML fields and your model’s fields:
xml_lookup = {}
xml_lookup = {'CAR-SLUG': 'slug'} # etc. etc.
You can populate this will all fields if you want, but my suggestion is to populate it only with those fields that have a unique constraint on them.
Next, while you are parsing your XML, populate a dictionary for each record, mapping each field:
for row in xml_file:
lookup_dict = {}
lookup_dict[xml_lookup[row['tag']] = row['value'] # Or something similar
car, created = Car.objects.get_or_create(**lookup_dict)
if created:
# Nothing matched, a new record was created
# Any any logic you need here
else:
# Existing record matched the search parameters
# Change/update whatever field to prevent the IntegrityError
car.model_slug = row['MODEL_SLUG']
# Set/update fields as required
car.save() # Save the modified object
- [Answered ]-No query executing on a table in postgresql
- [Answered ]-(Django) Passing 'context' (basic info) to every page, even forms?
- [Answered ]-Django User model customize validation
0👍
you can filter the duplicates car entries in memory first and then invoke create on new items, e.g,
uniq_attrs = ['slug', 'model_slug', ...]
existed_attrs = set()
for car in car_list:
# skip the duplicates
if any([(attr, car[attr]) in existed_attrs for attr in uniq_attrs):
continue
uniq_attrs.update([(attr, car[attr]) for attr in uniq_attrs])
# save the new car to db
Car.objects.save(....)
or you can try get_or_create on unique fields and then save other attribues with model save, e.g.,
for car in car_list:
attr_dict = {attr:car[attr] for attr in uniq_attrs}
car, created = Car.objects.get_or_create(**attr_dict)
# already created before
if created:
continue
# save other attributes
car.set(...)
car.set(...)
car.save()
- [Answered ]-Django: redirect url if slug is wrong
- [Answered ]-Multiple Choice Django Checkbox Form Validation