访问 Django 模板的 ManyToManyField 内容
Accessing a ManyToManyField's contents for a Django template
我正在制作一个低规格的 e-bay 克隆,我正在尝试实现监视列表功能,但问题是我无法访问监视列表模型中的 ManyToManyField,因此我可以使用我正在使用的模板中的字段。要向他们显示每个用户的监视列表,到目前为止我只得到这个结果:
但我需要得到这样的结果:
我使用的代码:
watchlist.html
{% extends "auctions/layout.html" %}
{% load static %}
{% block title %} {{name}}'s Watchlist {% endblock %}
{% block body %}
<h2>{{name}}'s Watchlist</h2>
{% for listing in watchlist %}
<div class='listing'>
<h3>{{ listing.list_title}}</h3>
{% if listing.img_url == "" %}
<a href='#'><img src="{% static 'auctions/img404.png' %}" class='img-fluid'></a>
{% else %}
<a href='#'><img src="{{ listing.img_url }}" class="img-fluid" alt='image of {{ listing.list_title }}'></a>
{% endif %}
<p>
{{ listing.desc }}
</p>
<p>
Current Bid: ${{ listing.start_bid }}
</p>
{% if listing.category == "" %}
<p>Category: No Category Listed</p>
{% else %}
<p>Category: {{ listing.category }}</p>
{% endif %}
<a href='#' class='btn btn-primary' id='go'>Go To Listing</a>
</div>
{% endfor %}
{% endblock %}
views.py
def render_listing(request, title):
if request.method == "POST":
form = BidForm(request.POST)
bid = int(request.POST['new_bid'])
listing = Auction_Listing.objects.get(list_title=title)
comments = Auction_Comments.objects.all().filter(auction_id=listing)
if bid < listing.start_bid:
error = True
else:
error = False
listing.start_bid = bid
listing.save()
return render(request, 'auctions/listing.html', {
"listing": listing,
"form": form,
"comments": comments,
"error": error
})
else:
form = BidForm()
listing = Auction_Listing.objects.get(list_title=title)
comments = Auction_Comments.objects.all().filter(auction_id=listing)
return render(request, 'auctions/listing.html', {
"listing": listing,
"form": form,
"comments": comments,
"error": False
})
@login_required
def watchlist_render(request):
user = request.user.id
username = request.user.username
watched = Watchlist.objects.filter(user_id=user)
return render(request, 'auctions/watchlist.html', {
"watchlist": watched,
"name": username
})
models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.db.models.deletion import CASCADE
CATEGORIES = [
('Appliances', 'Appliances'),
('Tech', 'Tech'),
('Gaming', 'Gaming'),
('Fashion', 'Fashion'),
('Sports and Fitness','Sports and Fitness'),
('Other','Other'),
("Hygiene and Medicine","Hygiene and Medicine"),
("Stationery","Stationery"),
('Decor', 'Decor'),
('Furniture','Furniture'),
('Cars and Mechanical Things','Cars and Mechanical Things'),
("Tools","Tools")
]
# Create models here
class User(AbstractUser):
pass
class Auction_Listing(models.Model):
user_id = models.IntegerField(default=1)
list_title = models.CharField(max_length=64)
desc = models.TextField(max_length=324)
img_url = models.URLField(max_length=200, null=True, blank=True)
start_bid = models.IntegerField()
category = models.CharField(choices=CATEGORIES, max_length=35, null=True, blank=True)
def __str__(self):
return f"ID:{self.id}, {self.list_title}: {self.desc}, {self.start_bid} posted by user:{self.user_id} in Category:{self.category}, url:{self.img_url}"
class Bids(models.Model):
bid = models.IntegerField(default=0)
user_id = models.IntegerField(default=1)
auction_id = models.ManyToManyField(Auction_Listing)
def __str__(self):
return f"ID:{self.id}, Bid {self.bid} posted by user:{self.user_id} on auction {self.auction_id}"
class Auction_Comments(models.Model):
user_id = models.IntegerField(default=1)
comment = models.TextField(max_length=324, default='N/A')
auction_id = models.ManyToManyField(Auction_Listing)
def __str__(self):
return f"ID:{self.id}, Comment: {self.comment} posted by user:{self.user_id} on auction {self.auction_id}"
class Watchlist(models.Model):
user_id = models.ForeignKey(User, on_delete=CASCADE,default=1)
auction_id = models.ManyToManyField(Auction_Listing, related_name='auction_listing')
def __str__(self):
return f"ID:{self.user_id} on auction {self.auction_id}"
在此先感谢您的帮助!
亲切的问候
PrimeBeat
编辑:@nigel222 请求的链接结果
啊 CS50W。我喜欢这门课程。无论如何,我知道你被困在哪里。您正在做的是在上下文中传递监视列表对象,而不是传递列表列表。
这就是您的 {% for listing in watchlist %}
失败的原因,因为 watchlist
是单个对象。
您可以做的是,在您的 views.py 中,获取已观看项目的完整列表,并将该列表作为上下文传入。所以:
@login_required
def watchlist_render(request):
user = request.user.id
username = request.user.username
# This will give you the Watchlist instance
watchlist = Watchlist.objects.filter(user_id=user)
# I would recommend renaming auction_id (in your models.py file) to `auctionItems` or 'listings'
# because it returns an object of type Auction_Listing, rather than just the id.
# for eg. watchlist.listings.all() allows you to instinctively understand what you're trying to do.
# Now you can extract the listings from the watchlist
listings = watchlist.auction_id.all()
return render(request, 'auctions/watchlist.html', {
"watchlist": listings,
"name": username
})
现在在您的模板中,您可以访问列表中的每个列表:{% for listing in listings %}
我正在制作一个低规格的 e-bay 克隆,我正在尝试实现监视列表功能,但问题是我无法访问监视列表模型中的 ManyToManyField,因此我可以使用我正在使用的模板中的字段。要向他们显示每个用户的监视列表,到目前为止我只得到这个结果:
我使用的代码:
watchlist.html
{% extends "auctions/layout.html" %}
{% load static %}
{% block title %} {{name}}'s Watchlist {% endblock %}
{% block body %}
<h2>{{name}}'s Watchlist</h2>
{% for listing in watchlist %}
<div class='listing'>
<h3>{{ listing.list_title}}</h3>
{% if listing.img_url == "" %}
<a href='#'><img src="{% static 'auctions/img404.png' %}" class='img-fluid'></a>
{% else %}
<a href='#'><img src="{{ listing.img_url }}" class="img-fluid" alt='image of {{ listing.list_title }}'></a>
{% endif %}
<p>
{{ listing.desc }}
</p>
<p>
Current Bid: ${{ listing.start_bid }}
</p>
{% if listing.category == "" %}
<p>Category: No Category Listed</p>
{% else %}
<p>Category: {{ listing.category }}</p>
{% endif %}
<a href='#' class='btn btn-primary' id='go'>Go To Listing</a>
</div>
{% endfor %}
{% endblock %}
views.py
def render_listing(request, title):
if request.method == "POST":
form = BidForm(request.POST)
bid = int(request.POST['new_bid'])
listing = Auction_Listing.objects.get(list_title=title)
comments = Auction_Comments.objects.all().filter(auction_id=listing)
if bid < listing.start_bid:
error = True
else:
error = False
listing.start_bid = bid
listing.save()
return render(request, 'auctions/listing.html', {
"listing": listing,
"form": form,
"comments": comments,
"error": error
})
else:
form = BidForm()
listing = Auction_Listing.objects.get(list_title=title)
comments = Auction_Comments.objects.all().filter(auction_id=listing)
return render(request, 'auctions/listing.html', {
"listing": listing,
"form": form,
"comments": comments,
"error": False
})
@login_required
def watchlist_render(request):
user = request.user.id
username = request.user.username
watched = Watchlist.objects.filter(user_id=user)
return render(request, 'auctions/watchlist.html', {
"watchlist": watched,
"name": username
})
models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.db.models.deletion import CASCADE
CATEGORIES = [
('Appliances', 'Appliances'),
('Tech', 'Tech'),
('Gaming', 'Gaming'),
('Fashion', 'Fashion'),
('Sports and Fitness','Sports and Fitness'),
('Other','Other'),
("Hygiene and Medicine","Hygiene and Medicine"),
("Stationery","Stationery"),
('Decor', 'Decor'),
('Furniture','Furniture'),
('Cars and Mechanical Things','Cars and Mechanical Things'),
("Tools","Tools")
]
# Create models here
class User(AbstractUser):
pass
class Auction_Listing(models.Model):
user_id = models.IntegerField(default=1)
list_title = models.CharField(max_length=64)
desc = models.TextField(max_length=324)
img_url = models.URLField(max_length=200, null=True, blank=True)
start_bid = models.IntegerField()
category = models.CharField(choices=CATEGORIES, max_length=35, null=True, blank=True)
def __str__(self):
return f"ID:{self.id}, {self.list_title}: {self.desc}, {self.start_bid} posted by user:{self.user_id} in Category:{self.category}, url:{self.img_url}"
class Bids(models.Model):
bid = models.IntegerField(default=0)
user_id = models.IntegerField(default=1)
auction_id = models.ManyToManyField(Auction_Listing)
def __str__(self):
return f"ID:{self.id}, Bid {self.bid} posted by user:{self.user_id} on auction {self.auction_id}"
class Auction_Comments(models.Model):
user_id = models.IntegerField(default=1)
comment = models.TextField(max_length=324, default='N/A')
auction_id = models.ManyToManyField(Auction_Listing)
def __str__(self):
return f"ID:{self.id}, Comment: {self.comment} posted by user:{self.user_id} on auction {self.auction_id}"
class Watchlist(models.Model):
user_id = models.ForeignKey(User, on_delete=CASCADE,default=1)
auction_id = models.ManyToManyField(Auction_Listing, related_name='auction_listing')
def __str__(self):
return f"ID:{self.user_id} on auction {self.auction_id}"
在此先感谢您的帮助!
亲切的问候
PrimeBeat
编辑:@nigel222 请求的链接结果
啊 CS50W。我喜欢这门课程。无论如何,我知道你被困在哪里。您正在做的是在上下文中传递监视列表对象,而不是传递列表列表。
这就是您的 {% for listing in watchlist %}
失败的原因,因为 watchlist
是单个对象。
您可以做的是,在您的 views.py 中,获取已观看项目的完整列表,并将该列表作为上下文传入。所以:
@login_required
def watchlist_render(request):
user = request.user.id
username = request.user.username
# This will give you the Watchlist instance
watchlist = Watchlist.objects.filter(user_id=user)
# I would recommend renaming auction_id (in your models.py file) to `auctionItems` or 'listings'
# because it returns an object of type Auction_Listing, rather than just the id.
# for eg. watchlist.listings.all() allows you to instinctively understand what you're trying to do.
# Now you can extract the listings from the watchlist
listings = watchlist.auction_id.all()
return render(request, 'auctions/watchlist.html', {
"watchlist": listings,
"name": username
})
现在在您的模板中,您可以访问列表中的每个列表:{% for listing in listings %}