我正在为电子商务项目使用Django通用视图。当我创建类别时,它的详细信息视图没有显示类别列表,而是直接将我带到第一个产品。
我的models.py:
from __future__ import unicode_literals
from django.core.urlresolvers import reverse
from django.db.models.signals import post_save
from django.db import models
from django.utils.text import slugify
class ProductQuerySet(models.query.QuerySet):
def active(self):
return self.filter(active=True)
class ProductManager(models.Manager):
def get_queryset(self):
return ProductQuerySet(self.model, using=self._db)
def all(self, *args, **kwargs):
return self.get_queryset().active()
class Product(models.Model):
title = models.CharField(max_length=200)
description = models.TextField(blank=True, null=True)
price = models.DecimalField(max_digits=12, decimal_places=2)
sale_price = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
active = models.BooleanField(default=True)
categories = models.ManyToManyField('Category', blank=True)
default = models.ForeignKey('Category', related_name='default_category', null=True, blank=True)
objects = ProductManager()
def __unicode__(self):
return self.title
def get_absolute_url(self):
return reverse("product_detail", kwargs={"pk":self.pk})
def image_upload_to(instance, filename):
title = instance.product.title
slug = slugify(title)
file_extension = filename.split(".")[1]
new_filename = "%s.%s"%(instance.id, file_extension)
return 'products/%s/%s' %(slug, new_filename)
class Variation(models.Model):
product = models.ForeignKey(Product)
title = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
image = models.ImageField(upload_to=image_upload_to)
price = models.DecimalField(max_digits=20, decimal_places=2)
sale_price = models.DecimalField(max_digits=20, decimal_places=2, null=True, blank=True)
inventory = models.IntegerField(null=True, blank=True)
active = models.BooleanField(default=True)
def __unicode__(self):
return self.title
def get_price(self):
if self.sale_price is not None:
return self.sale_price
else:
return self.price
def get_absolute_url(self):
return self.product.get_absolute_url()
def post_save_signal_receiver(sender, instance, created, *args, **kwargs):
product = instance
variations = product.variation_set.all()
if variations.count() == 0:
new_var = Variation()
new_var.product = product
new_var.title = "Original Product"
new_var.price = product.price
new_var.save()
post_save.connect(post_save_signal_receiver, sender=Product)
def image_upload_to(instance, filename):
title = instance.product.title
slug = slugify(title)
file_extension = filename.split(".")[1]
new_filename = "%s.%s"%(instance.id, file_extension)
return 'products/%s/%s' %(slug, new_filename)
class ProductImage(models.Model):
product = models.ForeignKey(Product)
image = models.ImageField(upload_to=image_upload_to)
def __unicode__(self):
return self.product.title
class Category(models.Model):
title = models.CharField(max_length=120, unique=True)
slug = models.SlugField(unique=True)
description = models.TextField(null=True, blank=True)
active = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
def __unicode__(self):
return self.title
def get_absolute_url(self):
return reverse("category_detail", kwargs={"slug": self.slug })
我的观点:
from django.contrib import messages
from django.shortcuts import render, get_object_or_404, Http404, redirect
from django.db.models import Q
from django.views.generic.detail import DetailView
from django.views.generic.list import ListView
from .models import Product, Variation, Category
from .forms import VariationInventoryFormSet
from .mixins import StaffRequiredMixin, LoginRequiredMixin
class CategoryListView(ListView):
model = Category
queryset = Category.objects.all()
template_name = "products/product_list.html"
class CategoryDetailView(DetailView):
model = Category
class VariationListView(StaffRequiredMixin, ListView):
model = Variation
queryset = Variation.objects.all()
def get_context_data(self, *args, **kwargs):
context = super(VariationListView, self).get_context_data(*args, **kwargs)
context["formset"] = VariationInventoryFormSet(queryset=self.get_queryset())
return context
def get_queryset(self, *args, **kwargs):
product_pk = self.kwargs.get("pk")
if product_pk:
product = get_object_or_404(Product, pk=product_pk)
queryset = Variation.objects.filter(product=product)
return queryset
def post(self, request, *args, **kwargs):
formset = VariationInventoryFormSet(request.POST, request.FILES)
if formset.is_valid():
formset.save(commit=False)
for form in formset:
new_item = form.save(commit=False)
if new_item.title:
product_pk = self.kwargs.get("pk")
product = get_object_or_404(Product, pk=product_pk)
new_item.product = product
new_item.save()
messages.success(request, 'Form Updated')
return redirect('products')
raise Http404
class ProductDetailView(DetailView):
model = Product
class ProductListView(ListView):
model = Product
queryset = Product.objects.all()
def get_context_data(self, *args, **kwargs):
context = super(ProductListView, self).get_context_data(*args, **kwargs)
context["query"] = self.request.GET.get("q")
return context
def get_queryset(self, *args, **kwargs):
qs = super(ProductListView, self).get_queryset(*args, **kwargs)
query = self.request.GET.get("q")
if query:
qs = self.model.objects.filter(
Q(title__icontains=query) |
Q(description__icontains=query)
)
try:
qs2 = self.model.objects.filter(
Q(price=query)
)
qs = (qs | qs2).distinct()
except:
pass
return qs
我在上面的CategoryListView中看到了map_list.html for view:
{% extends 'base.html' %}
{% load static %}
{% load staticfiles %}
{% block jumbotron %}
{% include 'jumbotron.html' %}
{% endblock jumbotron %}
{% block content %}
<div class="container">
<table class="table">
<tr>{% for object in object_list %}
<td><a href="{% url 'detail' pk=object.pk %}">{{ object.title }}</a></td>
<td>{{ product.description }}</td>
</tr>
{% endfor %}
</table>
</div>
{% endblock content %}
我的category_detail视图如下:
{% extends 'base.html' %}
{% block content %}
<h2>{{ object ))</h2>
<table class="table">
{% for product in object.product_set.all %}
<tr>
<td><a href="{{ product.get_absolute_url }}">{{ product.title }}</a> </td>
{% endfor %}
</tr>
</table>
{% endblock content %}
我的分类网址是:
url(r'^$', CategoryListView.as_view(), name='categories'),
url(r'^(?P<slug>[\w-]+)/$', CategoryDetailView.as_view(), name='category_detail'),
我可以在localhost:8000/categories
看到类别正常但是当我点击链接时,它会转到单个产品页面而不是类别列表。
我的根URL是:
from django.conf.urls import url, include, patterns
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from .views import (
base
)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^blog/', include('blog.urls', namespace='blog')),# Name space makes your urls unique even if they are of same name in multiple apps
url(r'products/', include('products.urls')),
url(r'categories/', include('products.urls_categories')),
url(r'^$', base, name='home'),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)