Thomas Schwärzl
Thomas Schwärzl

Reputation: 9917

custom-unique Field with relation to ManyToManyField

let's start with the model

#models.py
class Project(models.Model):
    owner = models.ForeignKey(User)
    name = models.CharField(max_length=100)

class Issue(models.Model):
    project = models.ForeignKey(Project)
    title = models.CharField(max_length=100)
    status = models.ForeignKey('Status')


class Status(models.Model):
    name= models.CharField(max_length=10, help_text=u'eg open, closed...')
    default = models.BooleanField(default=False)
    project = models.ManyToManyField(Project)

    def save(self, *args, **kwargs):
        if self.default:
            #self.__class__.objects.filter(default=True, project=self.project).update(default=False)
            pass

I'd like to set all default to False when a user selects on another Status the default option. How could I achieve this?

Edit:

A user will be able to create custom Status for his project. So, let's say the user got 2 Projects - they are called Audi and BMW.

Now the user creates a Status for an Issue. It's name will be open and he selects it to be default for all Issues within the Project BMW. All issues within the project BMW will get the default status open. Great!

Now the user creates another Status for an Issue. This time the name will be new and he selects it to be default for all his Projects!

So, what I need is something (with as less queries as possible) that sets the first Status open within BMW to default = false.

Upvotes: 0

Views: 52

Answers (2)

schacki
schacki

Reputation: 9533

    def save(self, *args, **kwargs):
        if self.default:
            for status in Status.objects.filter(default=True,project__in=self.project.all()):
                status.default=False
                status.save()
        super(Status,self).save(*args,**kwargs)

Upvotes: 1

colons
colons

Reputation: 279

You could create a single-instance Settings model with a ForeignKey Status relationship:

class Settings(models.Model):
    default_status = models.ForeignKey('Status')

You may want to enforce there only being one Settings instance.

Alternatively, you could perform the un-defaulting in save():

if self.default:
    for status in self.__class__.objects.all():
        if status != self:
            status.default = False
            status.save()

Note that if you're overriding Model.save(), you'll want to use super() to re-instate the original behaviour of that function. See Overriding predefined model methods in the Django documentation.

Upvotes: 1

Related Questions