Utilizzando un approccio simile a Saul, ma leggermente scopo diverso:
class TrueUniqueBooleanField(BooleanField):
def __init__(self, unique_for=None, *args, **kwargs):
self.unique_for = unique_for
super(BooleanField, self).__init__(*args, **kwargs)
def pre_save(self, model_instance, add):
value = super(TrueUniqueBooleanField, self).pre_save(model_instance, add)
objects = model_instance.__class__.objects
if self.unique_for:
objects = objects.filter(**{self.unique_for: getattr(model_instance, self.unique_for)})
if value and objects.exclude(id=model_instance.id).filter(**{self.attname: True}):
msg = 'Only one instance of {} can have its field {} set to True'.format(model_instance.__class__, self.attname)
if self.unique_for:
msg += ' for each different {}'.format(self.unique_for)
raise ValidationError(msg)
return value
Questa implementazione alzerà un ValidationError
quando si tenta di salvare un altro record con un valore True.
Inoltre, ho aggiunto l'argomento unique_for
che può essere impostato su qualsiasi altro campo nel modello, per controllare vera unicità solo per i record con lo stesso valore, come ad esempio:
class Phone(models.Model):
user = models.ForeignKey(User)
main = TrueUniqueBooleanField(unique_for='user', default=False)
fonte
2016-07-12 23:57:24
Buona domanda. Sono anche curioso di sapere se è possibile impostare un simile vincolo.So che se hai semplicemente creato un vincolo univoco finirai con solo due possibili righe nel tuo database ;-) –
Non necessariamente: se utilizzi un NullBooleanField, dovresti essere in grado di avere: (a True, a Falso, qualsiasi numero di NULL). –
Secondo [la mia ricerca] (http://stackoverflow.com/a/39374169/2996101), [@semente] (http://stackoverflow.com/a/12269037/2996101) risponde, tiene conto dell'importanza di rispettando il vincolo a livello di database, modello e (admin) mentre fornisce un'ottima soluzione anche per una tabella '' 'through''' di' '' ManyToManyField''' che necessita di un vincolo '' 'unique_together''' . – raratiru