django基本使用(part1)
一、基础安装
安装django
安装数据库PostgreSQL
二、创建项目
django-admin startproject mysite
三、cd进入mysite文件夹,运行项目
python manage.py runserver 8000
四、在mysite文件夹 创建应用
python manage.py startapp polls
五、简单显示文本
#第一步:在polls/views下创建视图
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the polls index.")
#第二步:为创建的视图创建映射的url.在polls/urls下:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),#route:url路径,views:视图,name:代表名称便于引用
]
#第三步:在根路径mysite/urls下注册polls/urls,在mysite/urls.py下:
from django.urls import include, path
from django.contrib import admin
urlpatterns = [
path('polls/', include('polls.urls')), #include代表路径分发
path('admin/', admin.site.urls),
]
#第四步:在浏览器中打开http:// localhost:8000 / polls /,将会显示:
Hello, world. You're at the polls index.
六、更改设置文件,在mysite/settings.py中修改数据库的设置
1、数据库的设置
使用sqlite3的数据库设置:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': 'mydatabase', } }
使用PostgreSQL,必须同时安装psycopg2
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'mydatabase', 'USER': 'mydatabaseuser', 'PASSWORD': 'mypassword', 'HOST': '127.0.0.1', 'PORT': '5432', } }
2、注册app
在INSTALLED_APPS中默认情况下已包含的应用程序
django.contrib.admin- 管理网站。你会很快使用它。django.contrib.auth- 一个认证系统。django.contrib.contenttypes- 内容类型的框架。django.contrib.sessions- 会话框架。django.contrib.messages- 消息传递框架。django.contrib.staticfiles- 一个管理静态文件的框架。
其中一些应用程序至少使用了一个数据库表,所以我们需要在数据库中创建表格,然后才能使用它们,执行命令:
python manage.py migrate
注册自己项目的app:
‘polls.apps.PollsConfig’
七、创建模型
from django.db import models class Question(models.Model): question_text = models.CharField(verbose_name=‘问题描述’,max_length=200)#在admin中显示'问题描述',而不是question_text,max_length必须设置,默认字段名称为question_text; pub_date = models.DateTimeField('date published')# #pub_date = models.DateField('date published') class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE)#添加外键 choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0)#设置默认值
备注:如何在templets模板中引用字段的verbose_name
fields=Question._meta.fields#将获取所有的字段field对象列表,可以通过遍历
for field in fields:
print(field.name) #字段名称,可以通过对象的反射机制获取对应的字段值
print(field.verbose_name) #获取verbose_name
from django.shortcuts import render from django.http import HttpResponse,Http404 from django.template import loader from .models import CompanyList,ReportType,BalanceSheet # Create your views here. def index(request): objs = BalanceSheet.objects.all() exclude_fields = ('id',) params = [f for f in BalanceSheet._meta.fields if f.name not in exclude_fields] #obj._meta.fields获取obj所有的字段对象 import collections data = collections.OrderedDict() #建立有序的字典 for parm in params: values = [getattr(obj, parm.name) for obj in objs] data[parm.verbose_name]=values context = { 'data':data, } return render(request, 'financilaMangement/index.html', context)
八、激活模型
python manage.py makemigrations
python manage.py migrate
九、使用数据库API
#跳入交互式Python shell并使用Django提供的免费API
python manage.py shell
>>> from polls.models import Question, Choice # Import the model classes we just wrote. # No questions are in the system yet. >>> Question.objects.all() <QuerySet []> # Create a new Question. # Support for time zones is enabled in the default settings file, so # Django expects a datetime with tzinfo for pub_date. Use timezone.now() # instead of datetime.datetime.now() and it will do the right thing. >>> from django.utils import timezone >>> q = Question(question_text="What's new?", pub_date=timezone.now()) # Save the object into the database. You have to call save() explicitly. >>> q.save() # Now it has an ID. >>> q.id 1 # Access model field values via Python attributes. >>> q.question_text "What's new?" >>> q.pub_date datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>) # Change values by changing the attributes, then calling save(). >>> q.question_text = "What's up?" >>> q.save() # objects.all() displays all the questions in the database. >>> Question.objects.all() <QuerySet [<Question: Question object (1)>]>
修改模型,增加__str__方法:
from django.db import models class Question(models.Model): question_text = models.CharField(‘问题描述’,max_length=200)#在admin中显示问题描述,而不是question_text,max_length必须设置; pub_date = models.DateTimeField('date published')# #pub_date = models.DateField('date published') def __str__(self): return self.question_text 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 def was_published_recently(self): return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
再次运行pythonshell
>>> from polls.models import Question, Choice # Make sure our __str__() addition worked. >>> Question.objects.all() <QuerySet [<Question: What's up?>]> # Django provides a rich database lookup API that's entirely driven by # keyword arguments. >>> Question.objects.filter(id=1) <QuerySet [<Question: What's up?>]> >>> Question.objects.filter(question_text__startswith='What') <QuerySet [<Question: What's up?>]> # Get the question that was published this year. >>> from django.utils import timezone >>> current_year = timezone.now().year >>> Question.objects.get(pub_date__year=current_year) <Question: What's up?> # Request an ID that doesn't exist, this will raise an exception. >>> Question.objects.get(id=2) Traceback (most recent call last): ... DoesNotExist: Question matching query does not exist. # Lookup by a primary key is the most common case, so Django provides a # shortcut for primary-key exact lookups. # The following is identical to Question.objects.get(id=1). >>> Question.objects.get(pk=1) <Question: What's up?> # Make sure our custom method worked. >>> q = Question.objects.get(pk=1) >>> q.was_published_recently() True # Give the Question a couple of Choices. The create call constructs a new # Choice object, does the INSERT statement, adds the choice to the set # of available choices and returns the new Choice object. Django creates # a set to hold the "other side" of a ForeignKey relation # (e.g. a question's choice) which can be accessed via the API. >>> q = Question.objects.get(pk=1) # Display any choices from the related object set -- none so far. >>> q.choice_set.all() <QuerySet []> # Create three choices. >>> q.choice_set.create(choice_text='Not much', votes=0) <Choice: Not much> >>> q.choice_set.create(choice_text='The sky', votes=0) <Choice: The sky> >>> c = q.choice_set.create(choice_text='Just hacking again', votes=0) # Choice objects have API access to their related Question objects. >>> c.question <Question: What's up?> # And vice versa: Question objects get access to Choice objects. >>> q.choice_set.all() <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]> >>> q.choice_set.count() 3 # The API automatically follows relationships as far as you need. # Use double underscores to separate relationships. # This works as many levels deep as you want; there's no limit. # Find all Choices for any question whose pub_date is in this year # (reusing the 'current_year' variable we created above). >>> Choice.objects.filter(question__pub_date__year=current_year) <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]> # Let's delete one of the choices. Use delete() for that. >>> c = q.choice_set.filter(choice_text__startswith='Just hacking') >>> c.delete()
十、通过django提供的后台管理进行数据库操作
1、创建一个管理员用户
python manage.py createsuperuser
2、输入用户名、邮箱和密码
Username: admin Email address: admin@example.com Password: ********** Password (again): ********* Superuser created successfully.
3、注册项目的相关的数据库,在polls/admin.py 文件中:
from django.contrib import admin from .models import Question admin.site.register(Question)
4、重启服务器并打开网址:http://127.0.0.1:8000/admin/并用用户名和密码登陆,便可以看到添加的应用数据库后台。
十一、新增视图-路径-模板
在polls/views.py中:
def detail(request, question_id): return HttpResponse("You're looking at question %s." % question_id) def results(request, question_id): response = "You're looking at the results of question %s." return HttpResponse(response % question_id) def vote(request, question_id): return HttpResponse("You're voting on question %s." % question_id)
在polls/urls中添加对应的路径
from django.urls import path from . import views urlpatterns = [ # ex: /polls/ path('', views.index, name='index'), # ex: /polls/5/ path('<int:question_id>/', views.detail, name='detail'), # ex: /polls/5/results/ path('<int:question_id>/results/', views.results, name='results'), # ex: /polls/5/vote/ path('<int:question_id>/vote/', views.vote, name='vote'),#尖括号中的文字用于捕获url中的传递的值,并以关键字参数question_id=5传递给视图函数(views) ]
通过数据库api在视图中返回数据库中的数据,在polls/views中修改index视图函数:
from django.http import HttpResponse from .models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5]#返回queryset对象,共5个,每个对象代表一行数据。 output = ', '.join([q.question_text for q in latest_question_list])#通过列表生成式将上述5个对象question_text连接起来生成字符串 return HttpResponse(output) # Leave the rest of the views (detail, results, vote) unchanged
views通过调用template中的模板来返回数据
在templates中创建一个文件夹与项目名相同:polls,在templates/polls下创建一个模板文件,命名为index.html
在index.html中输入:
{% if latest_question_list %} <ul> {% for question in latest_question_list %} <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>#模板中使用.来引用变量属性 {% endfor %} </ul> {% else %} <p>No polls are available.</p> {% endif %}
修改views中的index函数,使用render返回模板,模板使用的参数;
from django.shortcuts import render from .models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] context = {'latest_question_list': latest_question_list} return render(request, 'polls/index.html', context)
返回404错误
from django.http import Http404 from django.shortcuts import render from .models import Question # ... def detail(request, question_id): try: question = Question.objects.get(pk=question_id) except Question.DoesNotExist: raise Http404("Question does not exist") return render(request, 'polls/detail.html', {'question': question})
简写返回404错误,get和get_object_or_404经常使用,filter和get_list_or_404成对使用:
from django.shortcuts import get_object_or_404, render from .models import Question # ... def detail(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, 'polls/detail.html', {'question': question})
将模板中的地址引用改为松耦合状态
{% if latest_question_list %} <ul> {% for question in latest_question_list %} #<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>#模板中使用.来引用变量属性 <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>#来源于urlconfig中的name,这样在更改url时就不需要对模板中引用的url进行修改了 {% endfor %} </ul> {% else %} <p>No polls are available.</p> {% endif %}
更进一步:由于一个django中可能有多个的应用程序,如果两个应用程序的urlconfig中都设置了name='detail'时,模板回产生引用混乱,因此,需要在模板和urlconfig中加入appname,以便区分
在polls/urls中修改为:
from django.urls import path from . import views app_name = 'polls' urlpatterns = [ path('', views.index, name='index'), path('<int:question_id>/', views.detail, name='detail'), path('<int:question_id>/results/', views.results, name='results'), path('<int:question_id>/vote/', views.vote, name='vote'), ]
在templates/polls/index.html中修改为:
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
#<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>#模板中使用.来引用变量属性
#<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>#来源于urlconfig中的name,这样在更改url时就不需要对模板中引用的url进行修改了
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
浙公网安备 33010602011771号