django入门必会操作2

项目和数据准备:

 学会看django官网

Django 中文网 官网

可以切换展示语言 

 

项目开始前的准备工作

入门1看完了,就可以了

  1. 创建django项目,及app并注册app   (项目和app名字 随便写,如myProject myApp)
  2. 连接mysql,启动成功 表示连成功
  3. 新建app的urls.py 和templates文件夹,并调试打通MTV
    1. templates文件下新增test.html 文件
    2. render渲染 templates 文件中的html
      def test(request):                            # 用来调试打通MTV的
          return  render(request,'test.html')
    3. 主urls.py中的写法,导入include,写法: 应用名.urls     ()
      from django.urls import path,include
      urlpatterns = [
          path('admin/', admin.site.urls),
          path('polls/',include("myApp.urls"))
      
      ]
    4. 应用内urls.py中,路由关联视图函数
      from django.urls import path
      from .views import test
      urlpatterns = [
          path('test/', test, name="test"),  # 用来调试的
      ]
      
    5. 访问路由触发视图函数,就能渲染 templates中的页面

开始做个小项目

第一步:建表

        建立  问题 和选项表,展示问题列表,以及能够跳转到问题详情

1.models.py,然后生成迁移文件后同步(代码在入门1)

class Question(models.Model):
    question_text =models.CharField(max_length=200)
    pub_date =models.DateTimeField('注释')


class Choice(models.Model):
    question = models.ForeignKey(Question,on_delete=models.CASCADE) # 外键被删除,这个也被删除
    choice_text =models.CharField(max_length=200)
    votes_num = models.IntegerField(default=0)

views.py

def test(request):                            # 用来调试打通MTV的
    return  render(request,'test.html')


def index(request):
    question_list=Question.objects.all()
    context = {"question_list": question_list}
    return render(request, 'index.html', context)


def detail(request,question_id):
    try :
        question  =Question.objects.get(pk=question_id)
        context ={"question":question}
    except Question.DoesNotExist:
        raise  Http404("quesion does not exist")        #from django.http import  Http404
    return render(request, 'detail.html', context)

应用内urls.py 补充路由

urlpatterns = [
    path('test/',views.test,name="test"),    # 用来调试的
    path('',views.index),
    path('<int:question_id>/',views.detail,name='detail')

]

在 templates文件中,新增index.html,以下内容放到body里面, polls ,为应用名


{% if question_list %}
    <ul>
    {% for question in question_list %}
        <li><a href="/polls/{{ question.id }}">{{ question.question_text }}</a></li>
    {% endfor %}

    </ul>
{% else %}
    <p> no polls are available</p>
{% endif %}

detail.html,以下内容放到body里面

   详情页
        <br>
        问题:{{ question.question_text }}
        <br>
   选项:

访问  地址Http://127.0.0.1:8000/polls/, 一开始没有数据,然后新增用户去admin页面新增点数据,要先注册模型,查看入门1

 添加后数据后

-------------------------------以上操作涉及的问题---------------------------------------------

  • 1.on_delete 外键删除逻辑:
  • 2.html中a标签 跳转路由的写法,有两种
  • 3.render返回数据给 html, 和html模板中数据的使用,见 入门1.
  • 4.主动 raise 一个404错误 

1.on_delete 外键删除逻辑:

2.html中a标签 跳转路由的写法,有两种

在index.html中

访问详情,如下这种方式是 硬编码 url(推荐这个)

 如果不要硬编码url,可以这么写(但一般不这样,麻烦..)

        {% url 'hello:detail' question.id %}

写法如上: 

        第一个是url

        第二个是 表示用哪个路由,用urls中定义的app_name  :  name

        第三个是 要传递的参数

3.主动 raise 一个404错误 

        raise Http404("quesion does not exist") # from django.http import Http404

第二步:继续优化,和详情页展示 问题的选项

 视图函数中,使用 get_object_or_404 来获取数据对象,

        1.视图函数中:get_object_or_404的作用,是代替了这部分代码

 如下是改用get_object_or_404,就方便多了

实现投票功能

接着先准备

  detail.html改一下, 要把选项展示出来:

使用choice_set.all 。 可以获取所有这个问题的答案

 

(上面截图中,form单词写错了)

第二步涉及知识点:

  •         get_object_or_404 获取数据,获取不到就返回404   ---见上面不解释了
  •         外键表名.表名_set.all  的用法:  用于查询哪些使用了某外键

外键表名.表名_set.all  的用法:

  •  对象. 表名_set 点all  表示全部
  • 对象. 表名_set 点get (pk=*)表示查询某一个

 

第三步:实现投票功能

form表单实现请求

        就还需要定义属性  action (写路由的) 和method

        需要定义一个表单,type为submit的。

类似这种:

 下一步:就定义一个视图函数,以及配置一个路由触发视图函数

 定义  vote的url,urls.py中添加

 path('<int:question_id>/vote',views.vote,name='vote')

定义视图函数:功能是

 views.py中添加  投票的视图函数

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])    # 参数表示请求过来时,选选择的哪一项
        
    # 表示没有选择时,点击确定按钮
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return render(request, 'detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:    # 这里的代码相当于是写在try里的
        selected_choice.votes_num += 1
        selected_choice.save()

用postman来触发 此视图函数。

完善form表单,用表单来实现请求:

<form action="/demo/{{ question.id }}/vote" method="post">
    {% for choice in question.choice_set.all %}
        <input type="radio" name="choice" value="{{ choice.id }}">
        <label>{{ choice.choice_text }}</label><br />
    {% endfor %}
<input type="submit" value="投票" />
</form>

 

 

接着再写一个 结果页面,投票完成后,可以跳转到这个页面。再吧上面投票视图中,最后改一下

使用HttpResponseRedirect  进行重定向

# return HttpResponse("投票成功") # 这句话改成下面这句话
return HttpResponseRedirect(f"/demo/{question.id}/results")

定义路由:
并且views.py中vote函数也用了 name为results 的url,这里先定义下

path('<int:question_id>/results',views.result,name='results')

 views.py中

def result(reuqest,question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(reuqest, 'results.html', {'question':question})

results.html

<h1>{{ question.question_text }}</h1>

<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }} -- {{ choice.votes_num }} 票</li>
{% endfor %}
</ul>

<a href="/demo/{{ question.id }}/">再次投票</a>

接着优化,没有选择投票,就点击时,页面反馈

{% if error_message %}
    <p><strong>{{ error_message }}</strong>><</p>
{% endif %}

成品效果

  •         form表单请求接口
  •         HttpResponseRedirect 重定向到某个页面

        

form表单请求接口

        form标签中的 action接要请求的接口,和请求方式 post  还是get

        form中的标签的 name属性,就是要传递的参数

HttpResponseRedirect重定向

detail.html 中,可以看见提交表单后,是访问的  ***/vote   请求投票接口

方式1:基本用法,加路由的参数如下:

        from django.http import HttpResponseRedirect

 方式2: 用reverse 使用命名来执行重定向

        from django.urls import reverse

     

其他知识:generic来定义通用视图(有什么好处,之后再理解):

views中

class IndexView(generic.TemplateView):
    template_name = "index.html"
    def get_context_data(self, **kwargs):
        question_list = Question.objects.all()
        context = {"question_list": question_list}
        return context

urls中

 path('test2/',views.IndexView.as_view()),

一样能访问

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值