Home > Software design >  I want to create a details page with two models for an auction site with django but keep getting Fie
I want to create a details page with two models for an auction site with django but keep getting Fie

Time:02-19

I am creating an ebay like aunction site, the details view page should reflect details from two models.

One of the models has the details of the current_bid (this is created when creating the listing), there is also the second model that contains new_bids (this is where the users who want to purchase the item can input their bids).

The issue(s) I'm having is how to put two models in my details view and also if you can confirm my current logic in finding out the highest bid (if this is correct or not).

MODELS.PY

class Auction(models.Model):
    ABSTRACT = 'AB'
    MODERN = 'MN'
    ILLUSTRATION = 'IN'

    select_category = [
        ('ABSTRACT', 'Abstract'),
        ('MODERN', 'Modern'),
        ('ILLUSTRATION', 'Illustration')
    ]

    title = models.CharField(max_length=25)
    description = models.TextField()
    current_bid = models.IntegerField(null=False, blank=False)
    image_url = models.URLField(verbose_name="URL", max_length=255, unique=True, null=True, blank=True)
    category = models.CharField(
        choices=select_category,
        max_length=12,
        default=MODERN,
        null=True, blank=True
    )
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

    class Meta:
        ordering = ['-created_at']

class Bids(models.Model):
    auction = models.ForeignKey(Auction, on_delete=models.CASCADE, related_name='bidding')
    user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='bidding')
    new_bid = models.DecimalField(max_digits=8, decimal_places=2)
    # new_bid = MoneyField(max_digits=10, decimal_places=2, null=False, blank=False, default_currency='USD', default=0)
    done_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['auction', '-new_bid']

FORMS.PY

class AuctionForm(forms.ModelForm):
    
    class Meta:
        model = Auction
        fields = ['title', 'description', 'current_bid', 'image_url', 'category']

class BidForm(forms.ModelForm):

    class Meta:
        model = Bids
        fields = ['new_bid']
        labels = {
            'new_bid': ('Choose your maximum bid'),
        }

VIEWS.PY

def listing_detail(request, listing_id):
    detail = get_object_or_404(Auction, pk=listing_id)
    if detail == None:
        messages.add_message(request, messages.ERROR, "This is not available") 
        return HttpResponseRedirect(reverse("index"))
    bid_queryset = Bids.objects.filter(detail=listing_id).order_by('new_bid').first()
    if bid_queryset == None:
        bid = detail.current_bid
    else:
        bid = bid_queryset.new_bid
    context = {'detail': detail}
    return render(request, 'auctions/details.html', context)


@login_required
def make_bid(request, listing_id):
    bid_item = get_object_or_404(Bids, pk=listing_id)
    each_listing = Auction.objects.get(pk=listing_id)
    try:
        highest_bid = each_listing.bidding.order_by('-new_bid')[0]
    except Bids.DoesNotExist:
        highest_bid = 0
    if request.method == 'POST':
        form = BidForm(request.POST)
        if form.is_valid:
            if form['bidding'] > highest_bid:
                bidding = form.save()
                messages.add_message(request, messages.SUCCESS, "Your bid is currently the highest") 
                return HttpResponseRedirect(reverse("index"))
            else:
                messages.add_message(request, messages.ERROR, "Your bid must be higher than the previous bid") 

    else:
        form = BidForm(initial={'each_listing': each_listing,
                                    'user': request.user,
                                    'amount': highest_bid})
        return render(request, 'auctions/details.html', {'form': form})   

DETAILS.HTML

        <section>
            <div >
                <div >
                    {% if detail.image_url %}
                        <img src='{{ detail.image_url }}' alt="{{ detail.title }}" style="width:100%">
                    {% else %}
                        <img src="https://demofree.sirv.com/nope-not-here.jpg">
                    {% endif %}  
               
                </div>
                <div >
                    <div style="width: 30rem;">
                        <div>
                            <h5>{{ detail.title }}</h5>
                            <hr>
                            <p>{{ detail.description }}</p>
                            <hr>
                            <p>{{ detail.current_bid }}</p>
                            <hr>
                            <p>{{ detail.new_bid }}</p>
                            <hr>
                            <button  >Place bid</button>
                            <button >Add to watchlist</button>
                        </div>
                      </div>
                </div>

                <form action="{% url 'auctions:listing_detail' listing.id %}" method="post">
                    {% csrf_token %}
                    {{form.as_p}}
                    <input type="submit" value="Submit">
                </form>

Right now, I'm having this error message

FieldError at /detail/15/
Cannot resolve keyword 'detail' into field. Choices are: auction, auction_id, done_at, id, new_bid, user, user_id
Traceback Switch to copy-and-paste view
C:\Users\USER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\exception.py, line 47, in inner
                response = get_response(request) …
Local vars
C:\Users\USER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\base.py, line 181, in _get_response
                response = wrapped_callback(request, *callback_args, **callback_kwargs) …
Local vars
C:\Users\USER\Downloads\commerce\commerce\auctions\views.py, line 95, in listing_detail
    bid_queryset = Bids.objects.filter(detail=listing_id).order_by('new_bid').first() 

URLS.PY

urlpatterns = [
    path("", views.index, name="index"),
    path("create/", views.create_listing, name="create_listing"),
    path("detail/<int:listing_id>/", views.listing_detail, name="listing_detail"),
    path("bid/<int:listing_id>/", views.make_bid, name="bid"),

CodePudding user response:

Either you should add pk or id field in listing_detail view

Try this :

def listing_detail(request, listing_id):
    detail = get_object_or_404(Auction, pk=listing_id)
    if detail == None:
        messages.add_message(request, messages.ERROR, "This is not available") 
        return HttpResponseRedirect(reverse("index"))
    bid_queryset = Bids.objects.filter(pk=listing_id).order_by('new_bid').first() # change here
    if bid_queryset == None:
        bid = detail.current_bid
    else:
        bid = bid_queryset.new_bid

Note :

Change this {% url 'auctions:bid' listing.id %} to {% url 'bid' listing.id %} make sure that listing.id is from template variables.

  • Related