python - Django 打开链接,它会做预设的事情(点击电子商务网站上的“男士”并让它自动过滤男士服装
问题描述
对不起,垃圾标题,我不知道该放什么,如果有人有任何改进,请发表评论,我会相应地更新。
问题
我目前正在做一个电子商务网站,并且已经完成了商店部分的设置(您可以在其中查看产品并根据您的需要进行过滤),现在在导航栏和其他位置,我有诸如“男士”之类的名称或“女性”,
我需要的是这些链接转到商店页面并根据链接自动过滤
所以如果我点击“男士”,它应该会进入商店页面,并返回已经过滤的显示男士产品的项目(最好男士类别内的所有选项都应该已经打勾,但这不是必需的)。然后您可以根据需要继续调整您的过滤器,就像您直接点击商店页面一样。
尝试过的解决方案
首先,我尝试建立一个系统,您可以在其中使用动态 URL 来查看来自例如“shop/women”的链接,但这需要与“shop/”完全相同,只是过滤,我试图像这样将它添加到我的 urls.py 文件中
path('shop/<str:category>/', Shop.as_view(), name="shop"),
我肯定做错了什么,因为即使我尝试手动尝试它,它也不起作用,并引发 NoReverseMatch 发现错误。我试图在网上查看,但找不到解决方案。
我也很感谢过滤系统的一些帮助,但这不一定是答案,我需要的主要是某种能够获取信息并对其进行过滤的方法。我认为对于任何对 Django 有丰富经验的人来说,这应该是相对容易的,
非常感谢你
代码
我把我认为必要的所有相关代码都放了,但如果有人需要更多,请询问
models.py 产品类
# Product details
class Product(models.Model):
# name
name = models.CharField(max_length=256)
# price
price = models.DecimalField(max_digits=5, decimal_places=2)
# date added, i can use this to figure out if the item is new
date_added = models.DateTimeField(auto_now_add=True)
# Whether the item is in stock
in_stock = models.BooleanField(default=True)
# If the product is on sale
sale = models.BooleanField(default=False)
# the price for sale, this can be blank since there won't always be a sale on
sale_price = models.DecimalField(null=True, blank=True, max_digits=5, decimal_places=2)
# times sold, use this for bestsellers, not sure how to do this though
times_sold = models.PositiveIntegerField(default=0)
# gender type, uses the GENDER_CHOICES, use this in search and homepage
gender = models.CharField(max_length=256, choices=GENDER_CHOICES, default='women')
# Items to show on homepage, so bestseller will show up on bestseller
home_page_show = models.CharField(max_length=256, choices=DOING_WELL_CHOICES, default='no')
# Choices for the category to place the product into, we zip it to make it Django compliant
# ('actual value','human readable value')
category = models.CharField(max_length=256, choices=zip(CATEGORY_CHOICES, CATEGORY_CHOICES), default='women-coat')
# Here are all the images
thumbnail = models.ImageField()
image_1 = models.ImageField(null=True, blank=True)
image_2 = models.ImageField(null=True, blank=True)
image_3 = models.ImageField(null=True, blank=True)
image_4 = models.ImageField(null=True, blank=True)
# PRODUCT DETAIL FIELDS
LOREM_IPSUM = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
brand = models.CharField(max_length=1000, blank=True, default=LOREM_IPSUM)
head_description = models.TextField(max_length=1000, blank=True, default=LOREM_IPSUM)
description_1 = models.TextField(max_length=1000, blank=True, default=LOREM_IPSUM)
description_2 = models.TextField(max_length=1000, blank=True, default=LOREM_IPSUM)
specification_1 = models.TextField(max_length=1000, blank=True, default=LOREM_IPSUM)
specification_2 = models.TextField(max_length=1000, blank=True, default=LOREM_IPSUM)
# SIZES AVAILABLE
xxs = models.BooleanField(default=True)
xs = models.BooleanField(default=True)
xss = models.BooleanField(default=True)
s = models.BooleanField(default=True)
m = models.BooleanField(default=True)
ml = models.BooleanField(default=True)
l = models.BooleanField(default=True)
xl = models.BooleanField(default=True)
# COLOURS AVAILABLE
colour = models.CharField(default='red', choices=COLOUR_CHOICES, max_length=256)
# String Representation
def __str__(self):
return self.name
# This function just makes sure we don't get an error if we try to load an image
# that doesn't exist, it tries to get the url, and if that fails, returns an empty string
def thumbnailurl(self):
try:
url = self.thumbnail.url
except:
url = ''
return url
# We're going to do the same thing here, except iterate through all the images and try each one individually
# this way, we can get as many working images as possible
def imagesurl(self):
# Set an empty string as images to store all the urls
images = []
# Iterate through each image
for image in [self.image_1, self.image_2, self.image_3, self.image_4]:
# Try except to catch any errors
try:
# Try to add the image url to the list
images.append(image.url)
# image doesn't exist
except:
# Add a blank
images.append('')
# Return the final product
return images
商店的views.py
class Shop(ListView):
# Set the model as Product, the rest is handled by Django
model = Product
# Name of HTML File to show
template_name = 'store/shop.html'
# What to refer to in the HTML file (injection)
context_object_name = 'products'
# If the request.method is POST (a filter request)
def post(self, request, *args, **kwargs):
# Function from utils.py
min_price, max_price, products = filter_shop(request)
print(min_price, max_price)
# Function from utils.py
data = cartData(self.request)
# Assigning keys to keys in context which can then be referenced in the html
# Pass is in the completed query as a option, plus cartitems for the cart
context_dict = {'products': products, 'cartitems': data['cartItems'], 'min_price': min_price,
'max_price': max_price, 'categories':category_choices()}
return render(request, 'store/shop.html', context_dict)
def get_context_data(self, *args, object_list=None, **kwargs):
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
# Function from utils.py
data = cartData(self.request)
# Assigning keys to keys in context which can then be referenced in the html
context['cartitems'] = data['cartItems']
# Wishlist
context['wishlistitems'] = data['wishlistitems']
# Min and max for slider
context['min_price'], context['max_price'] = 33, 99
context['categories'] = category_choices()
return context
用于商店应用的 urls.py
from django.urls import path
from .views import *
app_name = 'store'
urlpatterns = [
# Index
path('', Index.as_view(), name="index"),
# Shop, like searching
path('shop/', Shop.as_view(), name="shop"),
# Detail view of product
path('detail/<int:pk>', ProductDetail.as_view(), name="detail"),
# Cart and wishlist view, they are basically both the same
path('cart/', Cart.as_view(), name="cart"),
path('wishlist/',WishListView.as_view(),name="wishlist"),
# checkout view
path('checkout/', Checkout.as_view(), name="checkout"),
# contact page, STILL NEED TO ADD IN BLOG
path('contact/',Contact.as_view(),name="contact"),
# Function which runs to update the cart, look at views.py
path('update_item/', updateItem, name="update_item"),
# Function which runs to update the wishlist, very similar to above, look at views.py
path('update_wishlist/',updateWishList,name="update_wishlist"),
]
解决方案
我认为您遇到的问题有一些解决方案。
让我们从网址开始。我认为您可能遇到的问题是,如果您将这两行放在一起:
path('shop/', Shop.as_view(), name="shop"),
path('shop/<str:category>/', Shop.as_view(), name="shop"),
这些名称必须是唯一的,因此您应该将第二个名称称为“shop_category”或类似名称。另一个潜在问题:不要忘记在你的网址末尾添加一个“/”。所以你有这个:
path('shop/<str:category>', Shop.as_view(), name="shop"),
但这需要是这样的:
path('shop/<str:category>/', Shop.as_view(), name="shop"),
如果您要开始使用包含不同视图的更复杂的商店结构,那么我建议您将 url 切换到应用程序结构。为此,请创建一个名为 urls 的文件夹并将您拥有的内容添加为init .py,但不要将 shop 作为视图添加,而是包含另一个 url 列表作为命名空间。
urls/__init__.py
from django.urls import path, include
app_name = 'store'
urlpatterns = [
path('shop/', include('urls.shop', namespace='shop')),
(everything else as you have it)
]
然后,您可以添加另一个名为 shop.py 的文件并将特定于该命名空间的内容放入其中。
urls/shop.py
from django.urls import path
from .views import *
app_name = 'store'
urlpatterns = [
path('', Shop.as_view(), name="index"),
path('mens/', Shop.as_view(), name="shop"),
]
对于您的具体情况,这可能是矫枉过正。如果您需要使用实际不同的视图,我主要推荐这种方法。使用这种方法,您可以使用 revers("shop:mens") 或任何您命名的模式链接到这些。
最后一点建议(也许这应该是第一点)如果你还没有的话,我要看看 django-tables2 和 django-filters。这极大地简化了从查询集生成表和使用查询字符串过滤数据的过程。因此,您不必只将类别传递给您的视图,而是可以传递一个长查询字符串,例如“http://www.example.com/shop/?category=mens&size=small&foo=bar”。这将告诉您的视图如何一次过滤这三个指标。即使您没有实现 django-filters,我也建议您以这种方式进行过滤。
推荐阅读
- python - 在 Python 中比较两个字典的值,并返回差值大于 2 的值的键
- c# - 从图片框保存图像时参数无效异常
- jquery - Jquery如何在数据属性数组中选择包含特定值的元素?
- reactjs - “IntrinsicAttributes & Props”类型上不存在 className
- java - 如何将主类中的对象添加到其他类Java中的ArrayList
- laravel - 在 laravel 6 中未添加主键作为对外键的引用
- android - 如何使用 MOSHI 将 un json 字符串解析为列表
- r - R循环添加另一列而不是放下它(Gephi导出)
- java - Java Swing 无法删除组件
- javascript - 无法记录来自 Apollo 的数据