Django managers vs proxy models

I'm currently getting into proxy models and I actually cannot understand when we should give them respect. For me they look very similar to managers

Is there some differences or we can implement the same things using proxy models and managers?

The idea is that you can implement logic on the model, and thus change how model instances behave.

In other words, you could use:

class User(models.Model):
    first_name = models.CharField(max_length=128)
    last_name = models.CharField(max_length=128)

    def __str__(self):
        return f'{self.first_name} {self.last_name}'


class ReverseUser(User):
    class Meta:
        proxy = True

    def __str__(self):
        return f'{self.last_name} {self.first_name}'

so ReverseUser.objects.all() and User.objects.all() target the same database, essentially make the same query, but will present here users in a different way if you use str(…) on them.

A manager deals with what to retrieve whereas a (proxy) model deals with what to do with the (retrieved) data.

That being said, proxy models are rather rare. I think I have encounter them perhaps ~10-20 times., since it often does not make that much sense to start re-defining what to do with data. A use-case that I found interesting was that you can usually register a model only once for a ModelAdmin [Django-doc], but if you want to present the same records in multiple ModelAdmins, for example because some people are allowed to edit certain fields, or see others, that is quite complicated. A proxy model can be used then to present the same data in different model admins.

Django managers are classes that manage the database query operations on a particular model. Django model manager

Proxy models allow you to create a new model that inherits from an existing model but does not create a new database table. proxy model

Let me give you an example:

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    published_date = models.DateField()
    is_downloadable = models.BooleanField(default=True)

If this is your model

manager:

class BookMnanger(models.Manager):
    def by_link(self):
        return self.filter(is_downloadable=True)

and you new manager:

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    published_date = models.DateField()
    is_downloadable = models.BooleanField(default=True)
    # your new manager should register to your model
    downloading = BookMnanger()

now, your new custom manager can work as below:

my_books = Book.downloading.all()
print(my_books)

but the proxy:

class BookProxy(Book):
    class Meta:
        proxy = True

    def special_method(self):
        return f"{self.title} by {self.author}, published on {self.published_date}"

and your proxy can work like this:

book = BookProxy.objects.first() 
print(book.special_method()) 

proxies are the way to change behavior of your model but, managers will change your specific queries

I can give you more link about them, if you need?

Вернуться на верх