Reputation: 35
I have been researching how can I avoid using snippet of code over and over. The answer probably will involve using (generic) Class-based functions. However, I am a beginner in Django and this seems confusing. Here is my view in views.py:
@login_required(login_url='/login')
def view_list(request, listing_id):
bid = Bid.objects.all().filter(listing=listing_id).order_by('-id')
b_u = bid[0].user
listing = Listing.objects.get(pk=listing_id)
if request.method == "GET":
return render(request, "auctions/view_list.html", {
"form": BidForm(),
"total_bids": bid.count(),
"bid": None if bid == 0 else bid[0].bid,
"listing": listing,
"bid_user": "Your bid is the current bid." if request.user == b_u else None
})
else:
form = BidForm(request.POST)
if form.is_valid():
value = form.cleaned_data
if value['bid'] <= bid[0].bid:
error_check = True
return render(request, "auctions/view_list.html", {
"error_check": error_check,
"alert": f"Your bid is lower than the current bid $({bid[0].bid})! Try placing a higher one.",
"form": BidForm(),
"total_bids": bid.count(),
"bid": None if bid == 0 else bid[0].bid,
"listing": listing,
"bid_user": "Your bid is the current bid." if request.user == b_u else None
})
else:
error_check = False
new_bid = form.save(commit=False)
new_bid.user_id = request.user.id
new_bid.listing_id = listing.id
new_bid.save()
return render(request, "auctions/view_list.html", {
"error_check": error_check,
"alert": "Your bid was successfully placed!",
"form": BidForm(),
"total_bids": bid.count(),
"bid": None if bid == 0 else bid[0].bid,
"listing": listing,
"bid_user": "Your bid is the current bid." if request.user == b_u else None
})
And here is my template code:
{% extends "auctions/layout.html" %}
{% load humanize %}
{% load crispy_forms_tags %}
{% block body %}
{% if error_check == True %}
<div class="alert alert-warning" role="alert">
{{ alert }}
</div>
{% elif error_check == False %}
<div class="alert alert-success" role="alert">
{{ alert }}
</div>
{% endif %}
<div>
<h3>Listing: {{ listing.title }}</h3>
<img src="{{ listing.image }}" alt="Listings' Images">
<p>{{ listing.description }}</p>
{% if not bid %}
<strong>${{ listing.price|stringformat:"1.2f" }}</strong>
{% else %}
<strong>${{ bid|stringformat:"1.2f" }}</strong>
{% endif %}
<p> {{ total_bids }} bid(s) so far. {% if bid_user %} {{ bid_user }} {% endif %}</p>
<form method="POST" name="bidding" action="{% url 'view_list' listing.id %}">
{% csrf_token %}
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">$</span>
</div>
<div style="margin: 0; padding: 0 2px; height: 6px;">
{% crispy form %}
</div>
<div class="input-group-append" >
<span class="input-group-text">.00</span>
</div>
<input type="submit" class="btn btn-primary" value="Place Bid">
</div>
</form>
<h4>Details</h4>
<li>Listed by: {{ listing.user }} </li>
<li>Category: {{ listing.category }} </li>
<li>Listing created at: {{ listing.created_at }} </li>
</div>
{% endblock %}
So how can I avoid all this repetition and make the code more succinct. Also, this way when the user places a successful bid, the rendered template does not contain the new information from the form.
Upvotes: 0
Views: 97
Reputation: 2963
The pattern is very simple
def some_view(request):
form = SomeForm(request.POST or None)
if request.method == 'POST' and form.is_valid():
# Form processing
return render(request, "auctions/view_list.html", {
"form": form
})
Upvotes: 2