慕课网学习总结三 - MEDIA,分页

配置上传的文件

  • 在项目下新建一个media文件夹
  • 在setting.py中设置MEDIA_URL,指明文件上传到哪里的绝对路径MEDIA_ROOT
#seting.py



# 设置上传文件的路径

MEDIA_URL = '/media/'

MEDIA_ROOT = os.path.join(BASE_DIR,'media') #指定根目录

 

文件上传会跟image字段属性的upload里面拼接完整的路径

“/media/org/2018/月份/图片名字”

上传的图片在数据库中保存的是相对路径

为了要在模板显示上传图片,要加上{{ MEDIA_URL}}

 

  1. 要想使用{{ MEDIA_URL }},要先在settings中TEMPLATES 里面添加media处理器:'django.core.context_processors.media'
  2. 要添加处理图片相应路径的url
#setting.py



TEMPLATES = [
{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',

#添加图片处理器,为了在课程列表中前面加上MEDIA_URL
'django.template.context_processors.media',
],
},
},
]
from django.views.static import serve
from MxOnline.settings import MEDIA_ROOT




# 处理图片显示的url,使用Django自带serve,传入参数告诉它去哪个路径找,我们有配置好的路径MEDIAROOT
re_path(r'^media/(?P<path>.*)', serve, {"document_root": MEDIA_ROOT })

下载后台上传的文件:

数据表的 FileField字段,upload_to="course/resource/%Y/%m

class CourseResource(models.Model):
    #课程附件资源下载

    course = models.ForeignKey(Course, verbose_name="课程",on_delete=models.CASCADE)
    name = models.CharField(verbose_name="名称",max_length=100)
    download = models.FileField(verbose_name="资源文        
        件",upload_to="course/resource/%Y/%m",max_length=100)
    add_time = models.DateTimeField(verbose_name="添加时间", default=datetime.now)

 

与后台上传图片的处理机制类似:点击即可下载

<a href="{{ MEDIA_URL }}{{ course_resource.download }}" class="downcode" target="_blank" download="" data-id="274" title="">下载</a>

 

分页功能

详情见 https://github.com/jamespacileo/django-pure-pagination    

安装

pip install django-pure-pagination #注意版本  

在setting.py的INSTALLED_APPS中添加

INSTALLED_APPS = (
    ...
    'pure_pagination',
)

使用方法:

#views.py  eg



class OrgView(View):
    '''课程机构'''

    def get(self, request):
        # 所有课程机构
        all_orgs = CourseOrg.objects.all()

        # 有多少家机构
        org_nums = all_orgs.count()

        # 所有城市
        all_citys = CityDict.objects.all()

# 对课程机构进行分页,尝试获取前台get请求传递过来的page参数,如果是不合法的配置参数默认返回第一页         
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        # 这里指从allorg中取五个出来,每页显示5个         #注意:分页之后的对象是一个#Paginator集合对象,不再是queryset对象.遍历Paginator集合对象,要加上object_list属性

        p = Paginator(all_orgs, 5, request=request)      
# eg 遍历Paginator集合对象  eg: {% for org in all_orgs.object_list %}  {{org.name}} {% # endfor %}

        orgs = p.page(page)

        return render(request, "org-list.html", {
            "all_orgs": orgs,
            "all_citys": all_citys,
            "org_nums": org_nums,

        })
#org_list.html  在模板中   分页下角



<div class="pageturn">
    <ul class="pagelist">
        {% if all_orgs.has_previous %}   #判断当前页是否有上一页
            <li class="long"><a href="?{{ all_orgs.previous_page_number.querystring }}">上一页</a></li>
        {% endif %}
        {% for page in all_orgs.pages %}      #遍历所有页码
            {% if page %}
                {% ifequal page all_orgs.number %} #判断是否是当前页码,是的话显示 active
                    <li class="active"><a href="?{{ page.querystring }}">{{ page }}</a></li>
                {% else %}
                    <li><a href="?{{ page.querystring }}" class="page">{{ page }}</a></li>
                {% endifequal %}
            {% else %}
                <li class="none"><a href="">...</a></li>
            {% endif %}
        {% endfor %}
        {% if all_orgs.has_next %}  #判断当前页是否有下一页
            <li class="long"><a href="?{{ all_orgs.next_page_number.querystring }}">下一页</a></li>
        {% endif %}
    </ul>
</div>

 

路由分发:

#  urls.py

urlpatterns = [
    path("org/", include('organization.urls', namespace="org")),
]

要写app_name = 该app名字

# organization/urls.py


from organization.views import OrgView
from django.urls import path,re_path



# 要写上app的名字
app_name = "organization"


urlpatterns = [
    path('list/',OrgView.as_view(),name='org_list'),
]

路由分发在模板中url链接的写法:

<li class="active" ><a href="{% url 'org:org_list' %}">授课机构</a></li>

 

 

modelform:

既有forms表单的验证功能又具有对提交数据保存到数据库的功能

定义modelform类

将modelform类应用于view

#forms.py

from django import forms

from operation.models import UserAsk





class UserAskForm(forms.ModelForm):
    class Meta:
        model = UserAsk   #要关联的对应的数据表
        fields = ['name', 'mobile', 'course_name']  #要验证的数据表内的字段
#view.py
from django.http import HttpResponse

from .forms import UserAskForm





class AddUserAskView(View):
    """
    用户添加咨询
    """

    def post(self, request):
        userask_form = UserAskForm(request.POST)  #实例化验证对象
        if userask_form.is_valid():
            user_ask = userask_form.save(commit=True)  #将验证通过的数据保存到数据库
# 如果保存成功,返回json字符串,后面content type是告诉浏览器返回的数据类型,json数据必须这么写
            return HttpResponse('{"status":"success"}',             
                                 content_type='application/json')
        else:
# 如果保存失败,返回json字符串,并将form的报错信息通过msg传递到前端
            return HttpResponse('{"status":"fail", "msg":"添加出错"}', 
                                  content_type='application/json')
<div class="right companyright">
    <div class="head">我要学习</div>
    <form class="rightform" id="jsStayForm">
        <div>
            <img src="{% static 'images/rightform1.png' %}"/>
            <input type="text" name="name" id="companyName" placeholder="名字" maxlength="25"/>
        </div>
        <div>
            <img src="{% static 'images/rightform2.png' %}"/>
            <input type="text" name="mobile" id="companyMobile" placeholder="联系电话"/>
        </div>
        <div>
            <img src="{% static 'images/rightform3.png' %}"/>
            <input type="text" name="course_name" id="companyAddress" placeholder="课程名" maxlength="50"/>
        </div>
        <p class="error company-tips" id="jsCompanyTips"></p>
        <input class="btn" type="text" id="jsStayBtn" value="立即咨询 >"/>
        {% csrf_token %}
    </form>
</div>
#ajax代码

<script>
    $(function () {
        $('#jsStayBtn').on('click', function () {
            $.ajax({
                cache: false,
                type: "POST",
                url: "{% url "org:add_ask" %}",
                data: $('#jsStayForm').serialize(),
                async: true,
                success: function (data) {
                   if (data.status == 'success') {
                        $('#jsStayForm')[0].reset();
                        alert("提交成功")
                    } else if (data.status == 'fail') {
                        $('#jsCompanyTips').html(data.msg)
                    }
                },
            });
        });
    })
</script>

Ajax代码说明:

  • 第一行表示:其它代码执行完再执行
  • 给“立即咨询”按钮绑定click事件,点击后执行function()函数里面的代码
  • cache:false   这个参数默认True,表示缓存,这里改为false,表示不用缓存
  • type:post    以post方式发送数据
  • url:把请求发送到哪个url
  • data:发送到服务器的数据
  • async:ture   表示异步发送
  • success:请求成功时执行的回调函数,data是服务器返回过来的数据
  • 因为后台返回的数据是{"status’:"success"}或者{"status’:"fail"},这里做个判断
  • 如果是“success”,则把提交表单里面的数据清空,如果是“fail”,显示错误信息

 

url中的数据

?ct=pxjg&city=1,想后台发送了这2个数据,后台获取数据如下:      &是和,一起的意思

后端获取数据

 city_id = request.GET.get('city','')    #city_id = '1' 字符串类型

 ct = request.GET.get('ct','')       #ct = 'pxjg'

#后台根据获取的数据对数据库筛选,给前端返回数据

 

前端ajax添加评论:

前端代码:

<!--发布评论-->

<div id="js-pub-container" class="issques clearfix js-form">
<div class="wgt-ipt-wrap pub-editor-wrap " id="js-pl-input-fake">
<textarea id="js-pl-textarea" class="" placeholder="来说点啥呗!!!"></textarea>
</div>
<input type="button" id="js-pl-submit" class="pub-btn" data-cid="452" value="发表评论">
<p class="global-errortip js-global-error"></p>
</div>

ajax代码

<script type="text/javascript">

//添加评论

$('#js-pl-submit').on('click', function(){
    var comments = $("#js-pl-textarea").val()      #获取输入框输入的评论内容comments
    if(comments == ""){
        alert("评论不能为空")     #评论为空时,弹出框提醒
        return
        }
    $.ajax({
        cache: false,
        type: "POST",     #post方式请求提交
        url:"{% url 'course:add_comment' %}",
        data:{'course_id':{{ course.id }}, 'comments':comments},    #提交的数据    课程的id, 输入框内输入的评论 comments
        async: true,
        beforeSend:function(xhr, settings){
            xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");   #django自带csrf攻击防护,在提交前需要带上{{ csrf_token }}
},
        success: function(data) {                   #提交成功后,后台返回逻辑执行success代码:
        if(data.status == 'fail'){
            if(data.msg == '用户未登录'){         #返回json数据:   status == 'fail'   msg == '用户未登录'  ,返回登入页面
                window.location.href="/login/";
            }else{
                alert(data.msg)
                }
            }else if(data.status == 'success'){            #返回json数据:  tatus ==                     
            'success',刷新当前页面
            window.location.reload();//刷新当前页面.
                }
            },
            });
                });
            </script>

 

后端处理逻辑

#添加评论

class AddCommentsView(View):

'''用户评论'''

    def post(self, request):
        if not request.user.is_authenticated:
# 未登录时返回json提示未登录,跳转到登录页面是在ajax中做的
            return HttpResponse('{"status":"fail", "msg":"用户未登录"}', content_type='application/json')
        course_id = request.POST.get("course_id", 0)
        comments = request.POST.get("comments", "")
        if int(course_id) > 0 and comments:
# 实例化一个course_comments对象
            course_comments = CourseComments()
# 获取评论的是哪门课程
            course = Course.objects.get(id = int(course_id))
# 分别把评论的课程、评论的内容和评论的用户保存到数据库
            course_comments.course = course
            course_comments.comments = comments
            course_comments.user = request.user
            course_comments.save()
            return HttpResponse('{"status":"success", "msg":"评论成功"}', 
                                content_type='application/json')   #给用户返回json数据  
        else:
            return HttpResponse('{"status":"fail", "msg":"评论失败"}', 
                                   content_type='application/json')

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值