问题
My model looks like
class Article(models.Model):
article_type = models.ForeignKey(
ArticleType,
on_delete=models.CASCADE,
related_name='articles'
)
title = models.CharField(
max_length=100,
verbose_name='Article Title'
)
count = models.IntegerField(
verbose_name='Frequency Count'
)
def __str__(self):
return self.title
And I have a search api
class SearchViewSet(RetrieveModelViewSet):
serializer_class = ArticleSerializer
queryset = Article.objects.all()
query = self.request.query_params.get("query")
final_queryset = search(query,queryset,#some logic)
#logic to generate serialiser and return serialiser.data
serialiser = self.get_serializer(final_ueryset, many=True)
search
function returns a list of articles i.e
type(final_queryset) is List
and search function looks like
def search(search_query, search_queryset, no_of_result):
def_start = time.time()
final_matches = []
startswith_time_start = time.time()
startswith_matches = search_queryset.filter(name__startswith=search_query).distinct('article_id')[:no_of_result]
startswith_time_end = time.time()
for q in startswith_matches:
if(len(final_matches)<no_of_result):
final_matches.append(q)
else:
break
if(len(final_matches)<no_of_result):
contains_time_start = time.time()
contains_matches = search_queryset.filter(name__contains=search_query).distinct('article_id')[:no_of_result]
contains_time_end = time.time()
for q in contains_matches:
if(len(final_matches)<no_of_result):
if(q.entity_id not in entity_covered_ids):
final_matches.append(q)
else:
break
return final_matches
And. I wan't to return the articles order_by('count) as well.
Now I wan't to increase the count
of top 3 articles from the final_queryset is there a way of doing this.
回答1:
Add created_at
field in your model, then use this field to find top 3 item or latest 3 items like this, and then increase count
queryset = Article.objects.order_by('-created_at')[:3] # it will return a queryset of latest 3 items
for article in queryset:
article.count += 1
article.save()
serializer = ArticleSerializer(article)
Note: I only shared the logic part here, and i can't test it in my local, but it should work and help you to get the idea. Use it on your need.
回答2:
Figured out a way for doing this
Inserting objects.id
in list
would help instead of objects
as than list
can be converted to a queryset
i.e
def search(search_query, search_queryset, no_of_result):
def_start = time.time()
final_matches = []
startswith_time_start = time.time()
startswith_matches = search_queryset.filter(name__startswith=search_query).distinct('article_id')[:no_of_result]
startswith_time_end = time.time()
for q in startswith_matches:
if(len(final_matches)<no_of_result):
final_matches.append(q.id)
else:
break
if(len(final_matches)<no_of_result):
contains_time_start = time.time()
contains_matches = search_queryset.filter(name__contains=search_query).distinct('article_id')[:no_of_result]
contains_time_end = time.time()
for q in contains_matches:
if(len(final_matches)<no_of_result):
if(q.entity_id not in entity_covered_ids):
final_matches.append(q.id)
else:
break
return final_matches
and then
class SearchViewSet(RetrieveModelViewSet):
serializer_class = ArticleSerializer
queryset = Article.objects.all()
query = self.request.query_params.get("query")
final_queryset = search(query,queryset,#some logic)
final_queryset = Article.objects.filter(id__in=final_queryset)
articles = final_queryset.all()[:3]
for article in articles:
article.count += 1
article.save()
#logic to generate serialiser and return serialiser.data
serialiser = self.get_serializer(final_ueryset, many=True)
来源:https://stackoverflow.com/questions/62058526/increasing-the-count-field-of-model-whenever-a-search-is-applied