首先我们看看效果:
OK,这就是我们的首页。
在首页我们要做的是有几个后台功能,产品,解决方案,用户中心,新闻中心,客户等等,我们这里不一一介绍,首先我们创建相关的app。
代码结构如下:
其中DjangoUeditor是我们用到的第三方app,主要是为了提供富文本编辑。
当我们创建好了项目和app之后,我们先在setting里配置好我们的项目:
INSTALLED_APPS = [
'simpleui',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'product.apps.ProductConfig',
'mainframe.apps.MainframeConfig',
'usercenter.apps.UsercenterConfig',
'about.apps.AboutusConfig',
'activity.apps.ActivityConfig',
'news.apps.NewsConfig',
'DjangoUeditor',
]
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
]
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATICFILES_DIRS = [
os.path.join(BASE_DIR, '/static/'),
]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# request的session过期时间
SESSION_COOKIE_AGE = 60 * 60
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
# simpleui设置
# 统计分析
SIMPLEUI_ANALYSIS = False
# 服务器信息
SIMPLEUI_HOME_INFO = False
SIMPLEUI_STATIC_OFFLINE = True
SIMPLEUI_DEFAULT_THEME = 'x-blue.css'
SIMPLEUI_LOGO = '/static/img/logo.png'
SIMPLEUI_CONFIG = {
'system_keep': False,
'menu_display': ['产品及解决方案', '用户中心', '新闻中心', '关于我们', '业务管理', '基础设置', '认证和授权'],
}
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://192.168.1.212:6379',
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100},
"PASSWORD": "smartcity2020",
},
},
}
# session backend 使用配置
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
CACHE_MIDDLEWARE_SECONDS = 60 * 10
这里我们用到了redis的全局缓存,所以我们又增加了django.middleware.cache.UpdateCacheMiddleware和django.middleware.cache.FetchFromCacheMiddleware 2个中间件。这里后台我们使用的是simpleui。
再来看看我们的url.py
from django.contrib import admin
from django.conf.urls import url, include
import mainframe.views
import about.urls
import activity.urls
import news.urls
import product.urls
from django.views import static
from django.conf import settings
from DjangoUeditor import urls as DjangoUeditor_urls
from activity.views import consult, partnership
from about.views import partner
import usercenter.urls
urlpatterns = [
url('myzhcs/', admin.site.urls),
url(r'^$', mainframe.views.index, name='index'),
url('^about/', include(about.urls), name='about'),
url('^news/', include(news.urls), name='news'),
url('^product/', include(product.urls)),
url(r'^ueditor/', include(DjangoUeditor_urls)),
url(r'^static/(?P<path>.*)$', static.serve,
{'document_root': settings.STATIC_ROOT}, name='static'),
url(r'^media/(?P<path>.*)$', static.serve,
{'document_root': settings.MEDIA_ROOT}, name='media'),
url('solutions/', include(activity.urls)),
url(r'^consult/$', consult),
url(r'^partner/$', partner, name='partner'),
url(r'^partnership/$', partnership, name='partnership'),
url(r'mdeditor/', include('mdeditor.urls')),
url(r'^usercenter/', include(usercenter.urls)),
]
配置好了相关路由,我们继续去建立我们的models,这里调比较典型的来讲:
这里讲我们的新闻中心:下面看看我们的news这个app的models:
from django.db import models
from uuslug import slugify
from DjangoUeditor.models import UEditorField
class Dynamic(models.Model):
title = models.CharField(max_length=50, verbose_name='标题', unique=True)
create_time = models.DateTimeField('创建时间', auto_now_add=True) # 新增的时候修改该字段
update_time = models.DateTimeField('修改时间', auto_now=True) # 新增和添加的时候修改该字段
category = models.ForeignKey('mainframe.Category', verbose_name='新闻频道', on_delete=models.CASCADE, blank=False)
tag = models.ManyToManyField('mainframe.Category', related_name='tag', verbose_name='标签', blank=True)
body = UEditorField(verbose_name='详情', height=400, width=1200)
url_slug = models.SlugField(editable=False, max_length=250)
introduction = models.CharField(max_length=20, verbose_name='简介',blank=True)
img = models.ImageField(upload_to='img', verbose_name='封面', blank=True)
auth = models.CharField(verbose_name='作者', editable=False, max_length=20)
is_active = models.BooleanField(verbose_name='热点')
class Meta:
db_table = 'dynamic'
verbose_name = verbose_name_plural = '公司动态'
ordering = ('-update_time',)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
self.url_slug = slugify(self.title)
if not self.img:
self.img = '/img/default_new.png'
super(Dynamic, self).save(*args, **kwargs)
def get_next_obj(self):
if self.get_next_by_create_time():
return self.get_next_by_create_time()
else:
return
def get_prev_obj(self):
if self.get_previous_by_create_time():
return self.get_previous_by_create_time()
else:
return
然后看看我们的后台管理效果:
前端展示如下:
可以看到我们的热门文章里面已经有了它,点击热门标签也会出现:
我们点击新闻查看:
OK,没有问题。这里我们在基础设置里建立了字典,某些数据我们则是从字典里获取的:
我们直接上我们的admin来看看效果:
class ChannelFieldListFilter(admin.SimpleListFilter):
title = '所属频道'
parameter_name = 'chapter'
# 列表显示拥有哪些标签
def lookups(self, request, model_admin):
chapter = Category.objects.filter(category_id=1)
res = []
for c in chapter:
res.append((c.id, c.category_name))
return res
def queryset(self, request, queryset):
if self.value():
return queryset.filter(category__id__contains=self.value())
class TagFieldListFilter(admin.SimpleListFilter):
title = '所属标签'
parameter_name = 'tag'
def lookups(self, request, model_admin):
tag = Category.objects.filter(category_id=2)
res = []
for c in tag:
res.append((c.id, c.category_name))
return res
def queryset(self, request, queryset):
if self.value():
return queryset.filter(tag=self.value())
class DynamicAdmin(admin.ModelAdmin):
def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
context['adminform'].form.fields['tag'].queryset = Category.objects.filter(category_id="2")
context['adminform'].form.fields['category'].queryset = Category.objects.filter(category_id="1")
return super(DynamicAdmin, self).render_change_form(request, context, add, change, form_url, obj)
def show_tags(self, obj):
tag_list = []
for tag in obj.tag.all():
tag_list.append(tag.category_name)
return ','.join(tag_list)
show_tags.short_description = '所属标签'
def show_catalog(self, obj):
return obj.category
show_catalog.short_description = '所属频道'
readonly_fields = ('front_cover_img_data',)
def front_cover_img_data(self, obj):
if obj.img:
html_img = """ <a href='{}'></a><br/>
<div onclick='$(".my_set_image_img").hide();$(this).next().show();'>
<img src='{}' style='width:80px;height:60px;'>
</div>
<div class='my_set_image_img' onclick="$('.my_set_image_img').hide()" style="z-index:9999;
position:fixed; top:100px; left: 50%; display:none;">
<img src='{}' style='width:500px; height:500px;'>
</div>""".format(obj.img.url, obj.img.url, obj.img.url)
return mark_safe(html_img)
front_cover_img_data.short_description = "封面图片"
# image_data.short_description = '封面'
list_per_page = 10
list_filter = (ChannelFieldListFilter, TagFieldListFilter,'is_active')
search_fields = ('title',)
list_display = ['title', 'introduction', 'show_catalog', 'show_tags', 'front_cover_img_data', 'is_active',
'create_time',
'update_time', ]
filter_horizontal = ('tag',)
formfield_overrides = {
models.CharField: {'widget': TextInput(attrs={'style': 'width:80%', 'row': 1})},
}
fields = ('title', 'category', 'introduction', 'img', 'body', 'tag', 'is_active')
def save_model(self, request, obj, form, change):
username = request.user.get_full_name()
if not obj.auth:
obj.auth = username[::-1]
obj.auth = obj.auth.replace(" ", "")
obj.save()
admin.site.register(Dynamic, DynamicAdmin)
我们看看新增之后的后台显示效果:
下面来看看前端页面我们是如何搞定的:
{% extends 'news_base.html' %}
{% block body %}
<body class="tag-template tag-scenario nav-closed fixed-all">
{% endblock %}
{% block banner %}
<section class="tabbar">
<article>
<ul class="tabs">
<li><a class="tab-page area_tabbar" name="area_tabbar" href="{% url 'news' %}">全部</a></li>
{% for channel in channel_tag %}
<li><a class="tab-page area_tabbar" name="area_tabbar" href="{% url 'news-channel' channel.id %}">{{ channel.category_name }}</a></li>
{% endfor %}
</ul>
</article>
</section>
<section class="blog tag">
<article>
<div class="post-container">
<ul class="breadcrumb">
<li><a class="h5 detail" href="/news/">所有</a></li>
<li class="tag-slug" data-tag-url="/news/"><a class="h5 detail" href="/news/">所有</a>
</li>
</ul>
<div class="tag-parent">
<div class="posts">
<ul class="list">
{% for new in news %}
<li class="post featured">
<a class="area_posts" name="area_posts" href="/news/blog/{{ new.url_slug }}">
<figure style="background-image:url(/media/{{ new.img }});height: 200px"></figure>
</a>
<div>
<div class="post-desc">
<a class="area_posts" name="area_posts" href="/news/blog/{{ new.url_slug }}"><p class="h2">
{{ new.title }}</p></a>
<a class="area_posts" name="area_posts" href="/news/blog/{{ new.url_slug }}"><p
class="h6 detail text-overflow">{{ new.introduction }}</p></a>
</div>
<div class="post-meta">
<p class="h6 detail">
<img class="author-thumb"
src="/static/img/post.svg" alt=""
nopin="nopin">
<a>{{ new.auth }}</a>
<time class="post-date" datetime="2020-06-03">{{ new.create_time}}</time>
</p>
</div>
</div>
</li>
{% endfor %}
</ul>
<ul class="pagination">
{% if news.has_previous %}
<li class="prev"><a href="?page={{ news.previous_page_number }}"><</a></li>
{% else %}
<li class="prev disabled"><a href="#"><</a></li>
{% endif %}
{% for num in pageRange %}
{% if num == currentPage %}
<li class="number active">
<a href="?page={{ num }}">{{ num }}</a>
</li>
{% else %}
<li class="number">
<a href="?page={{ num }}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if news.has_next %}
<li class="next"><a href="?page={{ news.next_page_number }}">></a></li>
{% else %}
<li class="next disabled"><a href="#">></a></li>
{% endif %}
</li>
</ul>
</div>
</div>
</div>
<ul class="cards">
<li class="tags">
<input name="q" placeholder="搜索文章" maxlength="15">
<img class="search" src="/static/img/search.svg" alt="search" style="width: 25px">
<p class="h4">热门标签</p>
<ul>
{% for tag in tags_set %}
<li>
<a class="h6 area_tags" name="area_tags" href="/news/tag/{{ tag.0.1 }}">{{ tag.0.0 }}</a>
</li>
{% endfor %}
</ul>
</li>
<li class="hots">
<p class="h4">热门文章</p>
<ul>
{% for new in active_news %}
<li>
<a class="area_hots" name="area_hots" href="/news/blog/{{ new.url_slug }}">
<p class="h4">{{ new.title }}</p>
<p class="h6 detail">{{ new.create_time }}</p>
</a>
</li>
{% endfor %}
</ul>
</li>
</ul>
</article>
</section>
{% endblock %}
{% block menu %}
{% endblock %}
最后看看我们的缓存菜单以及新闻相关的views:
def get_session(func):
@wraps(func)
def function(request, *args, **kwargs):
solution = get_list_or_404(Solutions)
product = get_list_or_404(Product)
menu_list = []
product_list = []
if not request.session.get('menu_list', None):
for i in solution:
menu_list.append(
{'title': i.name, 'img': str(i.img), 'url_slug': i.url_slug, 'channle': i.channle, 'hot': i.hot
})
request.session["menu_list"] = menu_list
if not request.session.get('product_list', None):
for i in product:
product_list.append(
{'id': i.id, 'icon': str(i.icon), 'detail': i.detail, 'img': str(i.img),
'code_name': i.code_name, 'sort': i.sort, 'title': i.title, 'hot': i.hot,'summary':i.summary,
})
request.session["product_list"] = product_list
return func(request, *args, **kwargs)
return function
@get_session
@require_GET
def news(request):
dynamic = get_list_or_404(Dynamic)
contacts, pageRange, currentPage = paginate(dynamic, request)
active_news = []
active_num = 0
for new in dynamic:
if new.is_active and active_num < 10:
active_news.append(new)
active_num += 1
tags_set = get_tag(Dynamic)
_channel = Category.objects.filter(category_id=1)
channel_tag = _channel.values('id', 'category_name').distinct()
channels = {}
for i in dynamic:
if not channels.get(i.category.category_name):
channels[i.category.category_name] = [i]
else:
channels[i.category.category_name].append(i)
return render(request, 'news.html',
{'tags_set': tags_set, 'news': contacts, 'pageRange': pageRange, 'currentPage': currentPage,
'active_news': active_news, 'channels_content': channels, 'channel_tag': channel_tag}, )
下面展示其他界面的效果图:
产品手册点击进入之后界面如下:
需要源码着,请私信本人,售价20.