[Answer]-Restrict a model to access only rows with a specific condition?

1👍

For newly created items you can set the default value in model definition

class MyModel(models.Model):
    # a lot of fields
    foo = models.CharField(max_length=10, default='bar')

    # Set the manager
    objects = BarManager()

    def save(self, force_insert=False, force_update=False, using=None):
        self.foo = 'bar'
        super(MyModel, self).save(force_insert, force_update, using)

To achieve that MyModel.objects.all() should return only rows with foo=bar you should implement your custom manager. You can re-define the get_query_set method to add filtering.

class BarManager(models.Manager):
    use_for_related_fields = True

    def get_query_set(self):
        return super(BarManager, self).get_query_set().filter(foo='bar')

Update after @tuomassalo comment

1) The custom manager will affect all calls to MyModel.objects.get(id=42) as this call just proxy a call to .get_query_set().get(id=42). To achieve this you have to set Manager as default manager for model (assign it to objects variable).

To use this manager for related lookups (e.g. another_model_instance.my_model_set.get(id=42)) you need to set use_for_related_fields = True on you BarManager. See Controlling automatic Manager types in the docs.

2) If you want to enforce foo=bar then default value is not enough for you. You can either use pre_save signal or overwrite the save method on your model. Don’t forget to call the original save method.

I updated the MyModel example above.

👤Igor

Leave a comment