# Define Custom Query Sets in Model Managers for Code Reuse

Django provides a great way to query your database with few lines of code and without writing SQL. However, there are some cases when you'll find yourself repeating the same piece of code logic in a project.🥶

## Problem

Let's say we've added a new field to a model to create a `public_id` based on `uuid4`.

```python
class Product(models.Model):
    public_id = models.UUIDField(db_index=True, unique=True, default=uuid.uuid4, editable=False)
```

Basically, this `public_id` will be used instead of the `id` of an object to perform CRUD actions. 
Suppose that a user makes a request to retrieve a specific object in the database. 
A solid logic will look like this:

```python
public_id = kwargs.get("public_id")
try:
    product = Product.objects.get(public_id=public_id)
except ObjectDoesNotExist:
    raise Http404("Product does not exist")
```
Simple logic right here, until you are adding other models to your project that use the same `public_id` field and you find yourself repeating the same piece of code logic.

## Solution

Custom model managers allow developers to write extra methods for a model.

Returning to the example, let's create a custom `Manager` class for the `Product` model.

```python
class ProductManager(models.Manager):
    def get_object_by_public_id(self, public_id):
        try:
            instance = self.get(public_id=public_id)
            return instance
        except ObjectDoesNotExist as e:
            raise e

class Product(models.Model):
    public_id = models.UUIDField(db_index=True, unique=True, default=uuid.uuid4, editable=False)

    objects = ProductManager()
```

And when retrieving an object, the code will simply be:

```python
public_id = kwargs.get("public_id")

product = Product.objects.get_object_by_public_id(public_id)
```

If you have other models in the database, let's suppose a `Shop` model or a `User` model with also a `public_id` field. We can write an `AbstractManager` class.

```python
class AbstractManager(models.Manager):
    def get_object_by_public_id(self, public_id):
        try:
            instance = self.get(public_id=public_id)
            return instance
        except (ObjectDoesNotExist, ValueError, TypeError) as e:
            raise e

class ShopManager(AbstractManager):
    pass

class ProductManager(AbstractManager):
    pass

class Product(models.Model):
    public_id = models.UUIDField(db_index=True, unique=True, default=uuid.uuid4, editable=False)

    objects = ProductManager()

class Shop(models.Model):
    public_id = models.UUIDField(db_index=True, unique=True, default=uuid.uuid4, editable=False)

    objects = ShopManager()

product = Product.objects.get_object_by_public_id(public_id)
shop = Shop.objects.get_object_by_public_id(public_id)
``` 
🚀🚀🚀

You can learn more about managers in the official documentation of [Django](https://docs.djangoproject.com/en/4.0/topics/db/managers/).



*Article posted using [bloggu.io](https://bloggu.io). Try it for free.*
