【问题标题】:django tutorial: where does question_id come from?django 教程:question_id 来自哪里?
【发布时间】:2016-12-18 19:05:45
【问题描述】:

所以我正在尝试学习 django 并遵循本教程:https://docs.djangoproject.com/en/1.10/intro/tutorial01/

按照教程制作投票应用程序后,当我回头查看代码时,我只是看不出这个“question_id”来自哪里。创建模型时不会出现。

以下是模型代码:

from django.db import models
from django.utils import timezone
import datetime
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    def __str__(self):
        return self.question_text
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text= models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    def __str__(self):
        return self.choice_text

在 view.py 中:

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.http import Http404
from django.template import loader
from django.urls import reverse
from django.views import generic

from .models import Question
from .models import Choice
from django.utils import timezone

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):
        return render(request, 'polls/detail.html', {
             'question': question,
             'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

question_id 不知从何而来。

  1. 是不是在创建模型的时候,django会自动为每个实例创建一个model_id?

  2. 另外,另一个问题是他们为什么要执行“pk=question_id”并在此后使用 pk。有关系吗?

urls.py 中的代码:

from django.shortcuts import render
from django.conf.urls import url

from . import views

app_name = 'polls'

urlpatterns = [
    # ex: /polls/
    url(r'^$', views.IndexView.as_view(), name='index'),
    # ex: /polls/5/
    url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
    # ex: /polls/5/results/
    url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(),     name='results'),
    # ex: /polls/5/vote/
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
 ]
  1. 另外,当使用这样的通用视图时:

    类 DetailView(generic.DetailView): 模型 = 问题 template_name = 'polls/detail.html'

我们可以传入参数(比如 question_id)吗?

【问题讨论】:

  • question_id 不是模型的一部分,它是从 url 传递到视图的参数。
  • 请注意最后一个 URL 模式,您实际上是通过该模式定义参数的名称:url(r'^(?P&lt;question_id&gt;[0-9]+)/vote/$'。你有def vote(self, question_id),其中的参数与 URL 模式中的定义相匹配。

标签: python django


【解决方案1】:

urls.pyurlpatterns 列表中,您有这条路线:

url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote')

url实际上是一个正则表达式,所以一个字符串可以指定整个url系列。
question_id 是正则表达式的命名部分,它定义了该 url 的参数。

当视图,即views.vote被调用时,从url解析的question_id作为函数参数发送。

例如,如果一个客户端访问该 url:

 /123/vote/

然后视图函数会这样调用:

 vote(request=request, question_id=123)
  1. 是不是在创建模型的时候,django会自动为每个实例创建一个model_id?

是的。

  1. 另外,另一个问题是他们为什么使用“pk=question_id”并在之后使用 pk。有关系吗?

这里的 pk 代表“主键”。没关系,真的,不同的名称只是一个范围问题。

vote 视图的函数参数名称是“question_id”。 get_object_or_404question.choice_set.get 方法中的函数参数名称是“pk”。

它们只是指向同一个对象的不同名称(例如整数123)。

【讨论】:

    【解决方案2】:
    1. 您的说法是正确的,您可能想在此处查看 Django 模型的相关文档:https://docs.djangoproject.com/en/1.10/topics/db/models/#automatic-primary-key-fields

    其中特别指出:

    默认情况下,Django 为每个模型提供以下字段:

    id = models.AutoField(primary_key=True)
    

    这是一个自动递增的主键。

    如果您想指定自定义主键,只需指定 primary_key=True 在您的一个字段上。如果 Django 看到你 显式设置Field.primary_key,不会自动添加id 列。

    每个模型都需要一个字段才能具有primary_key=True( 显式声明或自动添加)。

    1. 您可能还想看看这个问题,它简要解释了 Django 中 ID 和主键之间的区别: What's the difference between Model.id and Model.pk in django?

    2. 你为什么不试试看;)

    【讨论】:

      【解决方案3】:

      根据您的问题,question_id 是您创建的 Choice 表的字段。如果您仔细查看代码,您可能会发现 question= models.Foreignkey ,这是指定选择表中的每个条目都与问题表中的每个问题相关的那个。

      我会要求你运行以下命令

      python manage.py sqlmigrate polls 0001

      当您观察输出时,它可以为选择表指定 question_id 字段,该字段间接对应于 Question 表的 id。

      url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
      

      所以当解析像http://127.0.0.1:8000/polls/34/vote这样的url时 question_id='34' 部分来自 (?P[0-9]+)。在模式周围使用括号“捕获”与该模式匹配的文本并将其作为参数发送给我们在views.py中创建的视图函数,?P定义将用于识别匹配模式的名称和[ 0-9]+ 是匹配数字序列(即数字)的正则表达式。

      另外,我们可以说 question_id 是表中每个条目的标识符。

      1.是不是在创建模型的时候,django会自动为每个实例创建一个model_id?

      是的,django 会自动为每个创建的实例分配唯一的 id

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-18
        • 2010-09-21
        • 1970-01-01
        • 1970-01-01
        • 2014-04-24
        • 2015-07-13
        • 1970-01-01
        相关资源
        最近更新 更多