Как получить текущий элемент в модели из запроса?

Когда нажимается кнопка отправки, я хочу иметь возможность узнать, на каком элементе был пользователь. Кнопка будет находиться на странице элемента, на которую попадает пользователь при нажатии на элемент. Эта кнопка является частью формы django (PlaceBid), которая позволяет пользователю сделать ставку на товар. Поэтому я хочу иметь возможность обновлять наивысшую ставку товара, если ставка выше, чем текущая. Это означает, что мне нужно знать, какой товар просматривал пользователь.

Я также хочу сохранить ставку в модели под названием Bid и в этой модели мне также нужно знать, для какого листинга сделана ставка.

Как мне получить нужный элемент из модели?

Модели:

  • Listing() является моделью для элемента

  • Bid() - модель для ставки

views.py:

def bid(request):
    if request.method == 'POST':
        form = PlaceBid(request.POST)
        if form.is_valid():
            current = Listing.objects.get(pk=request.id) # my attempt to get the current item
            highest = current.highest_bid
            if form.cleaned_data['bid'] < highest:
                obj = Bid()
                obj.price = form.cleaned_data['bid']
                obj.item = current
                obj.user = User.objects.get(pk=request.user.id)
                obj.save()
                current.highest_bid = form.cleaned_data['bid']
                current.save()
                return HttpResponseRedirect(request.path_info)

forms.py:

class PlaceBid(forms.Form):
    bid = forms.FloatField(required=False, widget=forms.NumberInput(attrs={
        'class': 'bid',
    }))

html:

<form action=" {% url 'bid' %} " method="post">
    {% csrf_token %}
    {{ bidForm }}
    <input type="submit" value="Place Bid" class="place-bid">
</form>

Вы не получите его из запроса. Спрячьте его в форме.

class PlaceBid(forms.Form):
    bid = forms.FloatField(required=False, widget=forms.NumberInput(attrs={
        'class': 'bid',
    }))
    listing_id = forms.IntegerField(widget=forms.HiddenInput())

Затем в вашем методе, который отображает форму (я использую представления на основе функций)

def view_listing(request, listing_id)

   listing = Listing.objects.get(id=listing_id)

   myForm = PlaceBid(initial={"listing_id" : listing_id})

   return render("whatever.html", {"listing" : listing, "form" : form })

Полагаю, что другим вариантом было бы хранить listing_id в сессии, но я стараюсь этого избегать.

С учетом ограниченного кода, я могу только предположить, что у вас есть форма торгов для каждого товара в цикле forloop. Пример:

{% for item in items %}
    ...
    <form action=" {% url 'bid' %} " method="post">
        {% csrf_token %}
        {{ bidForm }}
        <input type="submit" value="Place Bid" class="place-bid">
    </form>
    ...
{% endfor %}

Но вот два метода, которые можно сделать...

  1. Используйте скрытое поле ввода для хранения идентификатора объекта элемента, затем получите имя этого поля на сервере, чтобы получить значение идентификатора элемента.

    # html
    <form action=" {% url 'bid' %} " method="post">
        {% csrf_token %}
        {{ bidForm }}
        <input type="hidden" value="{{ item.id }}" name="item_id">
        <input type="submit" value="Place Bid" class="place-bid">
    </form>
    
    
    # views.py
    def bid(request):
        if request.method == 'POST':
            form = PlaceBid(request.POST)
            if form.is_valid():
                item_id = request.POST.get('item_id', None)
                current = Listing.objects.get(id=item_id)
                # rest of code follows...
    
  2. Передайте id элемента через url. ( Моя рекомендация)

    # html
    <form action=" {% url 'bid' item.id %} " method="post">
        {% csrf_token %}
        {{ bidForm }}
        <input type="submit" value="Place Bid" class="place-bid">
    </form>
    
    
    # urls.py 
    # update the necessary url to accept an id
    path('bid/<int:id>/', views.bid, name='bid')
    
    
    # views.py
    def bid(request, id):
        if request.method == 'POST':
            form = PlaceBid(request.POST)
            if form.is_valid():
                current = Listing.objects.get(id=id) # id passed to this method used here...
                # rest of code follows...
    

Кроме того, вместо Listing.objects.get(id=id) я бы предложил использовать get_object_or_404(Listing, id=id), так как это поможет справиться с любой потенциальной ошибкой, которую выкинет Listing.objects.get(id=id).

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