skip to Main Content

im working on a project using django framework.

Im having issues in showing on the html the recently viewed items where the user (logged in) clicked before.

This is my index.html that shows the recently_viewed items

<div class="mt-6 px-6 py-12 bg-gray-100 rounded-xl">
        <h2 class="mb-12 text-2xl text-center">Recently Viewed Items</h2>
        
        <div class="grid grid-cols-3 gap-3">
            {% if recently_viewed_qs %}
                {% for item in recently_viewed_qs %}
                    <div>
                        <a href="{% url 'item:detail' item.id %}">
                            <div>
                                <img src="{{ item.image.url }}" class="rounded-t-xl">
                            </div>
        
                            <div class="p-6 bg-white rounded-b-xl">
                                <h2 class="text-2xl">{{ item.name }}</h2>
                            </div>
                        </a>
                    </div>
                {% endfor %}
            {% else %}
                <p>No recently viewed items.</p>
            {% endif %}
        </div>
        
    </div>

What im getting is the response NO recently viewed items, so i guess is not entering in the for loop

This is my views.py (not all views but the fundamental ones to understand the problem)

def items(request):
    query = request.GET.get('query', '')
    category_id = request.GET.get('category', 0)
    categories = Category.objects.all()
    items = Item.objects.filter()
    
    
    
    if category_id:
        items = items.filter(category_id=category_id)

    if query:
        items = items.filter(Q(name__icontains=query) | Q(description__icontains=query))
    print(f'Session Data: {request.session.get("recently_viewed", [])}')

    return render(request, 'item/items.html', {
        'items': items,
        'query': query,
        'categories': categories,
        'category_id': int(category_id)
    })

def recently_viewed( request, pk ):
    print('Entered in the recently_viewed')

    if not "recently_viewed" in request.session:
        request.session["recently_viewed"] = []
        request.session["recently_viewed"].append(pk)
    else:
        if pk in request.session["recently_viewed"]:
            request.session["recently_viewed"].remove(pk)
        request.session["recently_viewed"].insert(0, pk)
        if len(request.session["recently_viewed"]) > 5:
            request.session["recently_viewed"].pop()
    request.session.modified =True


def detail(request, pk):
    item = get_object_or_404(Item, pk=pk)
    related_items = Item.objects.filter(category=item.category).exclude(pk=pk)[:3]
    ratings = Rating.objects.filter(item=item)
    
    recently_viewed(request,pk)
    print(Item.pk)
    recently_viewed_qs = Item.objects.filter(pk__in=request.session.get("recently_viewed", []))[:3]

    #recently_viewed = request.session.get('recently_viewed',[])


    #if pk not in recently_viewed:
    #    recently_viewed.append(pk)
    #recently_viewed = recently_viewed[-3:]
    #request.session['recently_viewed'] = recently_viewed
    #print(request.session['recently_viewed'])
    
    
    
    #recently_items = Item.objects.filter(id__in=recently_viewed)
    #print(f'recently_items{recently_items}')

    if ratings:
        average_rating = round(sum(rating.value for rating in ratings) / len(ratings), 2)
    else:
        average_rating = None
        
    user_rating = Rating.objects.filter(item=item, rated_by=request.user).first()
    

    if request.method == 'POST':
        print('Entered in the POST method')
        rating_form=RatingForm(request.POST)
            
        if rating_form.is_valid():
            rating = rating_form.save(commit=False)
            rating.item = item
            rating.rated_by = request.user
            form_submitted = True 
            rating.save()
    else:
        rating_form = RatingForm()
        form_submitted = False
        
    print(f'recently viewed qs {recently_viewed_qs}')
    
    return render(request, 'item/detail.html', {
        'item': item,
        'related_items': related_items,
        'ratings': ratings,
        'average_rating': average_rating,
        'rating_form': rating_form,
        'recently_viewed': recently_viewed_qs,
        #'recently_items': recently_items,
        'user_rating':user_rating,
        'form_submitted': form_submitted,
    })

The outputs of the prints are
Entered in the recently_viewed
<property object at 0x7f8d76b28bd0>
recently viewed qs <QuerySet [<Item: Red Shoes>, <Item: Green forest>, <Item: Pencils>]>

I dont understand why is not showing in my html, i have similar class that does almost the "same thing", that is obviously working but is not using the session.

<div class="mt-6 px-6 py-12 bg-gray-100 rounded-xl">
    <h2 class="mb-12 text-2xl text-center">Related items</h2>

    <div class="grid grid-cols-3 gap-3">
        {% for related_item in related_items %}
            <div>
                <a href="{% url 'item:detail' related_item.id %}">
                    <div>
                        <img src="{{ related_item.image.url }}" class="rounded-t-xl">
                    </div>

                    <div class="p-6 bg-white rounded-b-xl">
                        <h2 class="text-2xl">{{ related_item.name }}</h2>
                    </div>
                </a>
            </div>
        {% endfor %}
    </div>
</div>

Thanks for who will respond.

html of images showing

2

Answers


  1. Chosen as BEST ANSWER

    Fixed it, the problem was way too easy.

    The objects needed to be integrated in the other app called 'core' where the homepage of my website is.

    It was missing the context for the recently_viewed items.

    def index(request):
    items = Item.objects.all()[:6]
    categories = Category.objects.all()
    recently_viewed_qs = Item.objects.filter(pk__in=request.session.get("recently_viewed", []))[:3]
    
    print(f'recently_viewed in core : {recently_viewed_qs}')
    
    
    return render(request, 'core/index.html', {
        'categories': categories,
        'items': items,
        'recently_viewed':recently_viewed_qs
    })
    

  2. You are making a mistake and that is you are using value instead of key coming from your detail function.
    so it should be like this:

    <div class="mt-6 px-6 py-12 bg-gray-100 rounded-xl">
            <h2 class="mb-12 text-2xl text-center">Recently Viewed Items</h2>
            
            <div class="grid grid-cols-3 gap-3">
                {% if recently_viewed %}
                    {% for item in recently_viewed %}
                        <div>
                            <a href="{% url 'item:detail' item.id %}">
                                <div>
                                    <img src="{{ item.image.url }}" class="rounded-t-xl">
                                </div>
            
                                <div class="p-6 bg-white rounded-b-xl">
                                    <h2 class="text-2xl">{{ item.name }}</h2>
                                </div>
                            </a>
                        </div>
                    {% endfor %}
                {% else %}
                    <p>No recently viewed items.</p>
                {% endif %}
            </div>
            
        </div>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search