主要是对需求表Product进行设计,在此项目中,我们需要标题、联系人、电话等字段。可参考models.py文件。
设计字段如下:
class Product(models.Model): list_display = ("title", "type", "location") title = models.CharField(max_length=100,blank=True, null=True) type = models.IntegerField(default=0) pv = models.IntegerField(default=0) contact = models.CharField(max_length=10,blank=True, null=True) location = models.CharField(max_length=20,blank=True, null=True) phone = models.CharField(max_length=13, blank=True, null=True) weixin = models.CharField(max_length=50, blank=True, null=True) status = models.BooleanField(default=False) timestamp = models.DateTimeField(auto_now_add=True, null=True) expire = models.IntegerField(default=1) 复制代码
业务编写
本项目一共分为3个页面,分别是列表页、详情页、提交页。
我们一一讲解
首页
首先是首页,它的模版位于templates/app/index.html 它主要是用来展示首页内容, 并提交搜索词,到搜索接口,所有的接口都位于app/urls.py里面,如下
app_name = 'app' urlpatterns = [ path('index', views.IndexView.as_view(), name='index'), path('detail/<int:pk>', views.DetailView.as_view(), name='detail'), path('commit', views.CommitView.as_view(), name='commit') ] 复制代码
我们设置首页的路由为IndexView, 开始编写IndexView的代码。它的代码非常简单:
class IndexView(generic.ListView): model = Product template_name = 'app/index.html' context_object_name = 'product_list' paginate_by = 15 c = None def get_context_data(self, *, object_list=None, **kwargs): context = super(IndexView, self).get_context_data(**kwargs) paginator = context.get('paginator') page = context.get('page_obj') page_list = get_page_list(paginator, page) context['c'] = self.c context['page_list'] = page_list return context def get_queryset(self): self.c = self.request.GET.get("c", None) if self.c: return Product.objects.filter(type=self.c).order_by('-timestamp') else: return Product.objects.filter(status=0).order_by('-timestamp') 复制代码
详情页
我们再来开发详情页,从urls.py中看到,详情页是由DetailView来实现的,我们来窥探它的全貌:
class DetailView(generic.DetailView): model = Product template_name = 'app/detail.html' def get_object(self, queryset=None): obj = super().get_object() return obj def get_context_data(self, **kwargs): context = super(DetailView, self).get_context_data(**kwargs) return context 复制代码
它很简单,继承了DetailView通用模板类来显示详情。
提交页
最后再来看一下提交页,它是由CommitView来实现的。同样是观看代码:
class CommitView(generic.CreateView): model = Product form_class = CommitForm template_name = 'app/commit.html' @ratelimit(key='ip', rate='2/m') def post(self, request, *args, **kwargs): was_limited = getattr(request, 'limited', False) if was_limited: messages.warning(self.request, "操作太频繁了,请1分钟后再试") return render(request, 'app/commit.html', {'form': CommitForm()}) return super().post(request, *args, **kwargs) def get_success_url(self): messages.success(self.request, "发布成功! ") return reverse('app:commit') 复制代码
它是继承自CreateView,因为是创建操作嘛,在post中,我们通过ratelimit来限制提交次数,防止恶意提交。