Tengo este tipo de modelo, y quería ordenar por propiedad blog_views , cuál es la mejor manera de hacerlo.
Este es el modelo:
class Post(TimeStampedModel, models.Model): """Post model.""" title = models.CharField(_('Title'), max_length=100, blank=False, null=False) # TODO: Add image upload. image = models.ImageField(_('Image'), upload_to='blog_images', null=True, max_length=900) body = models.TextField(_('Body'), blank=False) description = models.CharField(_('Description'), max_length=400, blank=True, null=True) slug = models.SlugField(default=uuid.uuid4(), unique=True, max_length=100) owner = models.ForeignKey(User, related_name='posts', on_delete=models.CASCADE) bookmarks = models.ManyToManyField(User, related_name='bookmarks', default=None, blank=True) address_views = models.ManyToManyField(CustomIPAddress, related_name='address_views', default=None, blank=True) likes = models.ManyToManyField(User, related_name='likes', default=None, blank=True, ) class Meta: ordering = ['-created'] def __str__(self): """ Returns a string representation of the blog post. """ return f'{self.title} {self.owner}' @property def blog_views(self): """Get blog post views.""" return self.address_views.all().count() Leí sobre annotate pero no pude obtener una imagen clara, ¿cómo puedo formular esto en mi opinión?
class PostList(generics.ListCreateAPIView): """Blog post lists""" queryset = Post.objects.all() serializer_class = serializers.PostSerializer authentication_classes = (JWTAuthentication,) permission_classes = (PostsProtectOrReadOnly, IsMentorOnly) filter_backends = [filters.SearchFilter, filters.OrderingFilter] search_fields = ['title', 'body', 'tags__name', 'owner__email', 'owner__username' ]Quiero filtrar por una propiedad en la URL
No puede ordenar por un campo de método porque el orden se realiza en el nivel de la base de datos y la base de datos no tiene idea de que ese campo existe.
Pero puedes usar annotate así:
from django.db.models import Count class PostList(generics.ListCreateAPIView): ... queryset = Post.objects.annotate(address_views_count=Count('address_views')).order_by('address_views_count') Si desea que el orden sea opcional, puede usar filter_queryset :
class PostList(generics.ListCreateAPIView): def filter_queryset(self, request, queryset, view): ordering = self.request.GET.get("ordering", None) if ordering == 'blog_views': queryset = queryset.annotate(address_views_count=Count('address_views')).order_by('address_views_count') return queryset