0

I'm building a news website.I need display 48 hours most viewed news, this part is in the detail.html page. Now I'm using this method.

def newsDetailView(request, news_pk):
    news = get_object_or_404(News, id=news_pk)
    News.objects.filter(id=news_pk).update(pv=F('pv') + 1)
    time_period = datetime.now() - timedelta(hours=48)
    host_news=news.objects.filter(date_created__gte=time_period).order_by('-pv')[:7]

    return render(request, "news_detail.html", {
        'news': news,
        'host_news' : host_news
    })

It works very well, but my question is ,in oder to use cache conveniently,I want to separate the hot_news functions from def newsDetailView.

I have tried :

 def hot_news(request):
     time_period = datetime.now() - timedelta(hours=48)
     hot_news =News.objects.filter(add_time__gt=time_period).order_by('-pv')[:7]

     return render(request, "news_detail.html", {
         'most_viewedh': most_viewedh
     })

However I can't get the data, in detail.html. I guess the issue is because the url.

the link of the detail.html from the index.html is

 <a href="{% url 'news:news_detail' news.pk %}">

news:news_detail is the url of view def newsDetailView

So the url is directly to def newsDetailView and has nothing two do with def hot_news.

What should I do, so that I can render the data from def hot_news to the same page as def newsDetailView does?

William
  • 3,724
  • 9
  • 43
  • 76
  • Ajax is a good hint to do it if you want to handle the hot_news in a separate `view`. Ajax will query that `view`, and refresh this part in the `template` – Lemayzeur May 18 '18 at 23:09
  • yes,I think maybe class base view is another method right? – William May 18 '18 at 23:11
  • There are plenty other ways to do it, the logic behind cache that you said, one `view` would do with a `decorator`, you have to just tell django which value that you want to have as `cache` value & its duration. FBV or CBV it's up to which one you master very well. – Lemayzeur May 18 '18 at 23:17
  • Hi friend I have a new question, could you help?Thank you so much! https://stackoverflow.com/questions/50431810/the-queryset-value-for-an-exact-lookup-must-be-limited-to-one-result-using-slici – William May 20 '18 at 04:59

1 Answers1

2

So you are correct in saying that beacuse the url you are going to is 'news:news_detail' that is the only view that is loaded. If you did want to load data from another view you could use ajax to load just the hot_news data and insert that into the page.

Although if all that you want to achieve is caching of hot_news this is not required. You could instead make use of django's low level cache api like this:

from django.core.cache import cache

def newsDetailView(request, news_pk):
    news = get_object_or_404(News, id=news_pk)
    News.objects.filter(id=news_pk).update(pv=F('pv') + 1)


    # Get host_news from the cache
    host_news = cache.get('host_news')

    # If it was not in the cache, calculate it and set cache value
    if not host_news:

        time_period = datetime.now() - timedelta(hours=48)
        host_news=news.objects.filter(date_created__gte=time_period).order_by('pv')[:7]        

        # Sets the cache key host_news with a timeout of 3600 seconds (1 hour)
        cache.set('host_news', host_news, 3600)

    return render(request, "news_detail.html", {
        'news': news,
        'host_news' : host_news
    })

Docs on the low level cache api are here: https://docs.djangoproject.com/en/2.0/topics/cache/#the-low-level-cache-api

You may also have to look at setting CACHES in your settings.py if you haven't already done so

hwhite4
  • 695
  • 4
  • 6
  • Really appreciate it!This answer is so cool that helps me understand how to use low level cache api very well. – William May 19 '18 at 15:48
  • Hi friend I have a new question, could you help?Thank you so much! https://stackoverflow.com/questions/50431810/the-queryset-value-for-an-exact-lookup-must-be-limited-to-one-result-using-slici – William May 20 '18 at 04:59