So I have a Django auctions app, which has 3 models: Users, Listings, Bids.
When a user tries to place a bid on some listing, I want to check if the new_bid field in Bid model is bigger than start current_bid field in Listing model and if the new_bid is <= 0, it should return a message.
This is what I've done so far but when I click on 'Place bid' button, it does not implement this, the page doesn't redirect to an error page if the value is less than the current bid and doesn't update the bid if the user adds another one.
Why is this not working?
VIEWS.PY
def listing_detail(request, listing_id):
try:
detail = get_object_or_404(Auction, pk=listing_id)
except Auction.DoesNotExist:
messages.add_message(request, messages.ERROR, "This is not available")
return HttpResponseRedirect(reverse("index"))
bid_count = Bids.objects.filter(auction=listing_id).count()
context = {'detail': detail, 'bid_count': bid_count, 'bidForm': BidForm()}
return render(request, 'auctions/details.html', context)
#login_required
def make_bid(request, listing_id):
if request.method == 'POST':
form = BidForm(request.POST)
if form.is_valid:
each_listing = Auction.objects.get(pk=listing_id)
highest_bid = Bids.objects.filter(pk=listing_id).order_by('-new_bid').first()
new_bid = form.cleaned_data.get['new_bid']
if new_bid <= 0:
return render(request, 'auctions/details.html',
{"message": "Input an amount greater than 0"})
# messages.add_message(request, messages.SUCCESS, "Input an amount greater than 0")
elif new_bid <= highest_bid.new_bid:
messages.add_message(request, messages.ERROR, "Amount is low, please increase the bid")
else:
highest_bid = Bids(each_listing=each_listing, user=request.user, new_bid=new_bid)
highest_bid.save()
each_listing.current_bid = new_bid
each_listing.save()
return HttpResponseRedirect(reverse("index"))
messages.add_message(request, messages.SUCCESS, "Your bid is currently the highest")
else:
form = BidForm()
return render(request, 'auctions/details.html', {'bidForm': form})
else:
form = BidForm()
return render(request, 'auctions/details.html', {'bidForm': form})
MODELS.PY
class User(AbstractUser):
pass
class Auction(models.Model):
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)
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')
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'),
}
DETAILS.HTML
<div class="row container">
<div class="col-sm-7 pr-5">
{% 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 class="col-sm-5">
<div style="width: 30rem;">
<div>
<h5>{{ detail.title }}</h5>
<hr>
<p>{{ detail.description }}</p>
<hr>
<p>${{ detail.current_bid }}</p>
<p>{{ bid_count }}</p>
<hr>
<form action="{% url 'listing_detail' detail.id %}" method="post">
{% csrf_token %}
{{ bidForm }}
<input type="submit" class="btn btn-primary btn-block mt-3" value="Place bid">
</form>
<button class="btn-block btn-outline-primary mt-3">Add to watchlist</button>
</div>
</div>
</div>
Related
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 class="row container">
<div class="col-sm-7 pr-5">
{% 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 class="col-sm-5">
<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 class="btn btn-primary btn-block" >Place bid</button>
<button class="btn-block btn-outline-primary">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"),
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.
I am a student learning Django. I want to implement so that I receive the product code in the order(join model) DB when ordering a product, but it is difficult because I keep getting an error like the title. I think I will die because it hasn't been solved for too long.
When I use product.object.all(), all the query sets are loaded, and even when I use a filter, an error occurs. How can I solve this problem? It would be such an honor if you could reply.
Error Message
ValueError at /join/element_detail/ Cannot assign "<QuerySet
[<Product: 학잠>, <Product: 헤라 블랙쿠션>, <Product: 종근당 활력 비타민B>, <Product:
코디 순수 3겹데코>, <Product: 다이어리>, <Product: 화이트 스탠드 조명>, <Product: 파이썬 웹
프로그래밍 교재>, <Product: 나이키 후드집업>]>": "Join.product_code" must be a
"Product" instance.
join / views.py
join.product_code = product
This part appears to be the problem.
models.py
class Product(models.Model):
product_code = models.AutoField(primary_key=True)
username = models.ForeignKey(Member, on_delete=models.CASCADE, db_column='username')
category_code = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, related_name='products')
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True, unique=False, allow_unicode=True)
image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True)
benefit = models.TextField()
detail = models.TextField()
target_price = models.IntegerField()
start_date = models.DateField()
due_date = models.DateField()
class Meta:
ordering = ['product_code']
index_together = [['product_code', 'slug']]
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('zeronine:product_detail', args=[self.product_code, self.slug])
class Join(models.Model):
join_code = models.AutoField(primary_key=True)
username = models.ForeignKey(Member, on_delete=models.CASCADE, db_column='username')
product_code = models.ForeignKey(Product, on_delete=models.CASCADE, db_column='product_code')
part_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.join_code)
class Meta:
ordering = ['join_code']
My guess is that there is something wrong with this part.(join/views.py)
I think something went wrong in the process of receiving the product, but I don't know how.
join/views.py
def element_detail(request):
designated_object = Designated.objects.all()
element_object = Element.objects.all()
value_object = Value.objects.all()
product = Product.objects.all()
if request.method == "POST":
join = Join()
join.product_code = product
join.username = request.user
join.part_date = timezone.now()
join.save()
return render(request, 'zeronine/list.html')
return render(request, 'zeronine/detail.html', {'designated_object': designated_object,
'element_object': element_object,
'value_object': value_object})
zeronine/views.py
def product_in_category(request, category_slug=None):
current_category = None
categories = Category.objects.all()
products = Product.objects.all()
if category_slug:
current_category = get_object_or_404(Category, slug=category_slug)
products = products.filter(category_code=current_category)
return render(request, 'zeronine/list.html', {'current_category': current_category,
'categories':categories,
'products':products})
def product_detail(request, id, product_slug=None):
current_category = None
categories = Category.objects.all()
products = Product.objects.all()
product = get_object_or_404(Product, product_code=id, slug=product_slug)
designated_object = Designated.objects.filter(rep_price='True')
element_object = Element.objects.all()
value_object = Value.objects.all()
return render(request, 'zeronine/detail.html', {'product':product,
'products':products,
'current_category': current_category,
'categories':categories,
'designated_object': designated_object,
'element_object':element_object,
'value_object':value_object})
zeronine/detail.html
<form method="POST" style="margin-left: 110px;" action="{% url 'zeronine:element_detail' %}">
<div class="form-group row">
<label for="value_code" class="col-sm-2 col-form-label"><b>옵션</b></label>
<div class="col-sm-5">
<select type="text" class="form-control" name="value_code" id="value_code">
{% for value in value_object %}
{%if value.product_code == product %}
<option value="{{value.value_code}}">{{value.name}}</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
{% csrf_token %}
{% if not user.is_authenticated %}
<a onclick="alert('로그인 후 참여가 가능합니다.');" style="cursor:pointer;">
<button type="submit" style="background:black; border-color:black;" class="btn btn-primary"> 참여하기</button></a>
<a onclick="alert('로그인 후 찜하기가 가능합니다.');" style="cursor:pointer;">
<button type="submit" style="background:white; color:black; border-color:black;" class="btn btn-primary">찜하기</button></a>
{% else %}
<a onclick="alert('{{ product.name }} 공동구매 참여가 완료되었습니다.');" style="cursor:pointer;">
<button type="submit" action="{% url 'zeronine:element_detail' %}" style="background:black; border-color:black;" class="btn btn-primary"> 참여하기</button></a>
<a onclick="alert('{{ product.name }} 상품을 찜했습니다.');" style="cursor:pointer;">
<button type="submit" style="background:white; color:black; border-color:black;" class="btn btn-primary">찜하기</button></a>
{% endif %}
</form>
def element_detail(request):
designated_object = Designated.objects.all()
element_object = Element.objects.all()
value_object = Value.objects.all()
product = Product.objects.all()
if request.method == "POST":
product_id = request.POST.get('value_code') # new
product = Product.objects.get(product_code=product_id) # new
# Or
#product_ids = request.POST.getlist('value_code')
#products = Product.objects.filter(product_code__in=product_ids)
#loop all products and save example;
#for product in products:
# join = Join()
# join.product_code = product
# join.username = request.user
# join.part_date = timezone.now()
# join.save()
join = Join()
join.product_code = product
join.username = request.user
join.part_date = timezone.now()
join.save()
return render(request, 'zeronine/list.html')
Edited to include multiple values from template, I'm assuming of course.
I have two functions, one adds items to the cart and one removes. While I try to add the item to the cart I get an error:
FieldError at /add/1
Cannot resolve keyword 'book' into field. Choices are: author, author_id, bookorder, description, id, price, publish_date, review, stock, title
Where do I go wrong? Any help is appreciated!
models.py
from django.db.models.query import prefetch_related_objects
from django.utils import timezone
from django.contrib.auth.models import User
class Author(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
def __str__(self):
return "%s, %s" % (self.last_name, self.first_name)
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE, null=True, blank=True)
description = models.TextField()
publish_date = models.DateField(default=timezone.now)
price = models.DecimalField(decimal_places=2, max_digits=8)
stock = models.IntegerField(default=2)
class Meta:
verbose_name ='Book'
verbose_name_plural = 'Books'
db_table = 'book'
class Cart(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
active = models.BooleanField(default=True)
order_date = models.DateField(null=True)
payment_type = models.CharField(max_length=100, null=True)
payment_id = models.CharField(max_length=100, null=True)
def add_to_cart(self, book_id):
book = Book.objects.get(pk=book_id)
try:
preexisting_order = Book.objects.get(book=book, cart=self)
preexisting_order.quantity += 1
preexisting_order.save()
except BookOrder.DoesNotExist:
new_order = BookOrder.objects.create(
book=book,
cart=self,
quantity = 1
)
new_order.save
def remove_from_cart(self, book_id):
book = Book.objects.get(pk=book_id)
try:
preexisting_order = BookOrder.objects.get(book=book, cart=self)
if preexisting_order.quantity > 1:
preexisting_order.quantity -= 1
preexisting_order.save()
else:
preexisting_order.delete()
except BookOrder.DoesNotExist:
pass
class BookOrder(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
quantity = models.IntegerField()
views.py
from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import redirect, render
from .models import Book, BookOrder, Cart
def index(request):
context = {
}
return render(request, 'template.html', context)
def store(request):
books = Book.objects.all()
context = {
'books': books,
}
return render(request, 'base.html', context)
def book_details(request, book_id):
context = {
'book': Book.objects.get(pk=book_id),
}
return render(request, 'store/detail.html', context)
def add_to_cart(request, book_id):
if request.user.is_authenticated:
try:
book = Book.objects.get(pk=book_id)
except ObjectDoesNotExist:
pass
else:
try:
cart = Cart.objects.get(user=request.user, active=True)
except ObjectDoesNotExist:
cart = Cart.objects.create(
user=request.user
)
cart.save()
cart.add_to_cart(book_id)
return redirect('cart')
else:
return redirect('index')
def remove_from_cart(request, book_id):
if request.user.is_authenticated:
try:
book = Book.objects.get(pk=book_id)
except ObjectDoesNotExist:
pass
else:
cart = Cart.objects.get(user=request.user, active=True)
cart.remove_from_cart(book_id)
return redirect('cart')
else:
return redirect('index')
def cart(request):
if request.user.is_authenticated:
cart = Cart.objects.filter(user=request.user.id, active=True)
orders = BookOrder.objects.filter(cart=cart)
total = 0
count = 0
for order in orders:
total += (order.book.price * order.quantity)
count += order.quantity
context = {
'cart': orders,
'total': total,
'count': count,
}
return render(request, 'store/cart.html', context)
else:
return redirect('index')
cart.html
{% block body %}
<div class="col-md-8 col-md-offset-2 col-sm-12 maincontent col-center">
<div style="text-align:center;text-decoration:underline"><h3>Your Cart</h3></div>
<div class="cart_container">
{% for item in cart %}
<div class="cart_item">
<div class="cart_listing">
<span class="title">{{ item.book.title }}</span> by {{ item.book.author.first_name }} {{ item.book.author.last_name }}
</div>
<div class="cart_price">
<span class="cart_quantity">{{ item.quantity }} x $<span class="cart_value">{{ item.book.price }}</span></span>
Quantity: [+] / [-]
</div>
</div>
{% empty %}
<div>
There are no items in your cart.
</div>
{% endfor %}
<div class="cart_total">
<h4> Total: $<span class="cart_value">{{ total }}</span></h4>
</div>
</div>
</div>
</div>
{% endblock %}
base.html
{% block body %}
<div class="col-md-8 col-md-offset-2 col-sm-12 maincontent col-center" >
<div style="text-align:center"><h3>Welcome to our store!</h3></div>
{% for book in books%}
<div class="storefront_book_display">
<a href="{% url 'store:book_details' book.id %}">
<img src="{% static 'base/img/empty_cover.jpg' %}">
<span class="storefront_book_title">{{ book.title }}</span>
<span class="storefront_book_author">{{ book.author }}</span>
</a>
<span class="storefront_add_to_cart">
Add to cart
</span>
</div>
{% endfor %}
</div>
{% endblock %}
In your models.py > Cart > add_to_cart > preexisting_order = Book.objects.get(book=book, cart=self)
The book model doesn't have a field book
You probably meant to do preexisting_order = BookOrder.objects.get(book=book, cart=self)
This Code is working perfectly. The only thing I want to change is submit button "Vote" into "Voted" after user voted the option ,instead of displaying error message " You Already Voted".So that the user can know which options he voted already when he logs in to vote the option next time
urls.py
path('<slug>/',views.options,name='options'),
path('<slug>/vote/', views.vote, name='vote'),
models.py
class Category(models.Model):
name = models.CharField(max_length=250)
slug = AutoSlugField(populate_from='name')
details = models.TextField(blank=True)
image = models.ImageField(blank=True,upload_to='categories')
views = models.IntegerField(default=0)
created = models.DateTimeField(auto_now=True)
modified = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=True)
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "Categories"
class Option(models.Model):
name = models.CharField(max_length=250)
slug = AutoSlugField(populate_from='name')
image = models.ImageField(blank=True,upload_to='options')
details = models.TextField()
category = models.ForeignKey(Category, on_delete=CASCADE)
votes = models.IntegerField(default=0)
active = models.BooleanField(default=True)
def __str__(self):
return self.name
class Vote(models.Model):
option = models.ForeignKey(Option, on_delete=CASCADE)
voter = models.ForeignKey(User, on_delete=CASCADE)
slug = AutoSlugField(populate_from='option')
def __str__(self):
return self.voter
views.py
def options(request,slug):
category = Category.objects.get(slug=slug)
category.views += 1
category.save()
options = category.option_set.all().order_by('-votes')
if request.method == "POST":
if request.user.is_authenticated:
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.category = category
comment.user = request.user
comment.save()
messages.success(request, 'Comment Posted.')
else:
messages.error(request, 'You have to login first to give comment')
return redirect('rank:login')
else:
form = CommentForm()
return render(request, 'rank/options.html', {'options': options,'form':form,'title': 'options','category':category})
def vote(request,slug):
if request.user.is_authenticated:
option = Option.objects.get(slug=slug)
category = option.category
if Vote.objects.filter(slug=slug,voter_id=request.user.id).exists():
messages.error(request,'You Already Voted!')
return redirect('rank:options', category.slug)
else:
option.votes += 1
option.save()
voter = Vote(voter=request.user,option=option)
voter.save()
messages.success(request,'Voted.{} peoples also agree with you.'.format(option.votes-1))
return redirect('rank:options',category.slug)
else:
messages.error(request,"You have to login first to vote.")
return redirect('rank:login')
options.html
<ol type="1">
<center>{% bootstrap_messages %}</center>
{% for option in options %}
<div class="col-lg-6 col-md-6 mb-6">
<div class="card h-100">
<div class="card-body">
<b><li>
<img src="/media/{{option.image}}" width="400" height="300">
<h4>{{option.name}}
</h4>
<h5 class="card-text">{{ option.details}}</h5>
<h5>{{ option.votes }} votes</h5>
<form action="{% url 'rank:vote' option.slug %}" method="post">
{% csrf_token %}
<input type="submit" class="btn btn-success" value="Vote" >
</form>
</li></b>
</div>
<div class="card-footer">
<small class="text-muted"></small>
</div>
</div>
</div>
{% empty %}
<div class="card w-100">
<div class="card-body">
<h4>Item not available</h4>
</div>
</div>
{% endfor %}
</ol>
The simplest way to achieve this might be to add an attribute to each option to indicate whether the currently logged in user has voted on that option before you pass the options to the template.
For example:
def options(request,slug):
category = Category.objects.get(slug=slug)
category.views += 1
category.save()
options = category.option_set.all().order_by('-votes')
# Indicate whether the user has voted or not
for option in options:
option.has_voted = option.vote_set.filter(voter=request.user).exists()
...
return render(request, 'rank/options.html', {'options': options,'form':form,'title': 'options','category':category})
And then you can check the has_voted attribute in the template when you render the button:
{% if option.has_voted %}
You already voted
{% else %}
<input type="submit" class="btn btn-success" value="Vote" >
{% endif %}
I have a ModelForm that I'm using to upload files with and it doesn't want to work. I had it working yesterday but I'm not sure what was done to make it stop all of a sudden.
Here's my ModelForm:
class UserForm(forms.ModelForm):
description = forms.CharField(max_length=500, widget=forms.Textarea(attrs={'cols': 80, 'rows': 5}))
class Meta:
model = UserProfile
exclude = {'user', 'description'}
Here's the Model:
def get_image_path(instance, filename):
return os.path.join('images', str(instance.id), filename)
def get_video_path(instance, filename):
return os.path.join('videos', str(instance.id), filename)
def get_randfile_path(instance, filename):
return os.path.join('randfile', str(instance.id), filename)
class UserProfile(models.Model):
user = models.OneToOneField(User)
description = models.CharField(max_length=500, blank=True, null=True)
photo = models.FileField(upload_to=get_image_path, blank=True, null=True)
video = models.FileField(upload_to=get_video_path, blank=True, null=True)
rand_file = models.FileField(upload_to=get_randfile_path, blank=True, null=True)
def photo_name(self):
return os.path.basename(self.photo.name)
def video_name(self):
return os.path.basename(self.video.name)
Here's the View:
def detail(request, user_id):
user = get_object_or_404(User, pk=user_id)
userprofile = get_object_or_404(UserProfile, user=user)
year = datetime.now().year
userform = UserForm()
delvid = Del_Video()
if request.method == 'POST':
userform = UserForm(request.POST, request.FILES, instance=user)
delvid = Del_Video(request.POST)
if userform.is_valid():
userprofile.description = request.POST.get('description', userprofile.description)
userprofile.photo = request.FILES.get('photo', userprofile.photo)
userprofile.video = request.FILES.get('video', userprofile.video)
userprofile.rand_file = request.FILES.get('rand_file', userprofile.rand_file)
userprofile.save()
else:
messages.add_message(request, messages.INFO, 'Invalid Form')
userform = UserForm()
if delvid.is_valid():
if request.POST['Delete']:
userprofile.video.delete()
else:
delvid = Del_Video()
context = {'user': user, 'year': year, 'userform': userform, 'userprofile': userprofile, 'delvid': delvid}
return render(request, 'users/detail.html', context)
And here is the form in the template:
<div class="row">
<div class="col-md-4">
<h4>Update User:</h4>
{% if userform.errors %}
<h6>{{ userform.errors }}</h6>
{% endif %}
{% if messages %}
{% for message in messages %}
<h5>{{ message }}</h5>
{% endfor %}
{% endif %}
<form action="{% url 'users:detail' user.id %}" method="post" enctype="multipart/form-data" data-ajax="false">
{% csrf_token %}
{{ userform.as_p }}
<input type="submit" value="Update">
</form>
</div>
</div>