views:

508

answers:

1

I have a problem with deleting my objects. I wrote a delete method which get a list of IDs of objects to be deleted. This works fine for objects and for objects with foreign keys, but it fails if i have a OneToOneField relationship to the object which i want to delete.

This is my delete method:

@login_required
def delete_objects(request, model, selected_ids):
    '''
    capsulate a bulk delete method
    delete all objects found for the given model
    fails silently since model.delete() always fails silently
    '''
    object_list = model.objects.filter(pk__in=selected_ids)
    count = object_list.count()
    if count == 1:
        name = model._meta.verbose_name.title()
    else:
        name = model._meta.verbose_name_plural.title()
    object_list.delete()
    request.user.message_set.create(message='Successfully deleted %s %s' % (count,name))
    return

Till now I just tested it with Contact objects. Now I added a PhoneNumber model to my models. The PhoneNumber model has a OneToOneField relationship to the Contact model. If no PhoneNumber object or one PhoneNumber object is assigned to the Contact object i can delete it. But if I relate more than one PhoneNumber object to a Contact object i get an error.

This is the error message that i get:

MultipleObjectsReturned at /crm/contacts/
get() returned more than one PhoneNumber -- it returned 3! Lookup parameters were {'contact__pk': 4L}
Request Method: POST
Request URL:    http://127.0.0.1:8000/crm/contacts/
Exception Type: MultipleObjectsReturned
Exception Value:    
get() returned more than one PhoneNumber -- it returned 3! Lookup parameters were {'contact__pk': 4L}

I read in the django docs

deleting objects

that "any objects which had foreign keys pointing at the object to be deleted will be deleted along with it." This is the goal I want to accomplish.. but now i get an error. All I want is the objects to be deleted :D

Actually is this maybe a design problem? Is it wrong when I relate more than one PhoneNumber object to a Contact object with a OneToOneField relationship? I have chosen OneToOneField since the phone number is unique and should be related to only one contact.

+3  A: 

Is it wrong when I relate more than one PhoneNumber object to a Contact object with a OneToOneField relationship?

You got it. Change the relationship to a foreign key in PhoneNumber and set the unique option for the PhoneNumberField.

Should end up like this:

class PhoneNumber(models.Model):
    # some fields...
    number = PhoneNumberField(unique=True)
    contact = models.ForeignKey(Contact, related_name="phone_numbers")

Also, just to make sure I understand how you want the constraints set up: This example assumes that a phone number will only appear once in the entire database and therefore also that only one contact can have that phone number.

In case you wanted something less restrictive, use unique_together in the model's Meta options like so:

class PhoneNumber(models.Model):
    # some fields...
    number = PhoneNumberField()
    contact = models.ForeignKey(Contact, related_name="phone_numbers")

class Meta:
    unique_together = ("number", "contact")

This will allow multiple contacts to have the same phone number, but a single contact cannot have that number more than once.

http://docs.djangoproject.com/en/dev/ref/models/options/#unique-together

John Debs
Took the words right outta me mouth :)
elo80ka
:D that saved my day. It works now. I got the idea of OneToOneField relationships wrong. I just wanted to make sure, that no other Contact can relate to the same PhoneNumber object. But this works fine with ForeignKeys. OneToOne Relationships are there to define a OneToOne Relationship, like the name tells us ;-) Thank you guys!
Tom Tom