from django.db import models
from django.db.models.signals import m2m_changed
from django.dispatch import receiver
from django.db.utils import IntegrityError

class Publisher(models.Model):
    name = models.CharField(max_length=30)

class Book(models.Model):
    """
    A Book may have multiple publishers.
    But a two books cannot have same name and a common publisher.
    
    """
    name = models.CharField(max_length=30)
    publishers = models.ManyToManyField(Publisher)

@receiver(m2m_changed, sender=Book.publishers.through)
def verify_uniqueness(sender, **kwargs):
    book = kwargs.get('instance', None)
    action = kwargs.get('action', None)
    publishers = kwargs.get('pk_set', None)

    if action == 'pre_add':
        for publisher in publishers:
            if Book.objects.filter(name=book.name).filter(publishers=publisher):
                raise IntegrityError('Book with name %s already exists for publisher %s' % (book.name, Publisher.objects.get(pk=publisher)))