已經(jīng)同步到gitbook逸爵,想閱讀的請(qǐng)轉(zhuǎn)到gitbook: Django 1.10 中文文檔
Writing your first Django app, part 7?
This tutorial begins where Tutorial 6 left off. We’re continuing the Web-poll application and will focus on customizing Django’s automatically-generated admin site that we first explored in Tutorial 2.
緊接著Tutorial 6寻定。我們繼續(xù)開(kāi)發(fā)投票應(yīng)用并主要關(guān)注Django自動(dòng)生成的admin站點(diǎn)澳骤,這部分我們?cè)?a target="_blank" rel="nofollow">教程2中已經(jīng)了解過(guò)。
Customize the admin form?
By registering the Question model with admin.site.register(Question), Django was able to construct a default form representation. Often, you’ll want to customize how the admin form looks and works. You’ll do this by telling Django the options you want when you register the object.
通過(guò)admin.site.register(Question)語(yǔ)句將Question模型注冊(cè)到admin锡移,Django會(huì)自動(dòng)生成該模型的默認(rèn)表單轩性。一般情況下巴刻,你需要定制表單的樣式和功能。這樣在你注冊(cè)模型的時(shí)候就需要告訴Django你想要的選項(xiàng)傍妒。
Let’s see how this works by reordering the fields on the edit form. Replace the admin.site.register(Question)
line with:
我們通過(guò)演示對(duì)表單字段的重新排序幔摸,來(lái)了解其工作原理。用以下代碼替換admin.site.register(Question)語(yǔ)句:
polls/admin.py
from django.contrib import admin
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fields = ['pub_date', 'question_text']
admin.site.register(Question, QuestionAdmin)
You’ll follow this pattern – create a model admin class, then pass it as the second argument to admin.site.register() – any time you need to change the admin options for a model.
一般遵循以下步驟——?jiǎng)?chuàng)建一個(gè)model admin類(lèi)颤练,然后作為admin.site.register()的第二個(gè)參數(shù)——你可以隨時(shí)修改模型的admin選項(xiàng)既忆。
This particular change above makes the “Publication date” come before the “Question” field:
這個(gè)操作將使“Publication date” 放在“Question” 字段之前:
This isn’t impressive with only two fields, but for admin forms with dozens of fields, choosing an intuitive order is an important usability detail.
只有兩個(gè)字段的情況下,感覺(jué)沒(méi)什么作用,但是對(duì)于有幾十個(gè)字段的表單來(lái)說(shuō)尿贫,采用更直觀的排序方式將是一個(gè)值得引起注意的細(xì)節(jié)問(wèn)題电媳。
And speaking of forms with dozens of fields, you might want to split the form up into fieldsets:
而且對(duì)于有幾十個(gè)字段的表單來(lái)說(shuō),你也許想要通過(guò)fieldsets來(lái)分隔開(kāi):
polls/admin.py
from django.contrib import admin
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date']}),
]
admin.site.register(Question, QuestionAdmin)
The first element of each tuple in fieldsets is the title of the fieldset. Here’s what our form looks like now:
fieldsets 內(nèi)元組的第一個(gè)字段是fieldsets的標(biāo)題庆亡。我們的表單看起來(lái)應(yīng)該像以下這樣了:
Adding related objects?
OK, we have our Question admin page, but a Question
has multiple Choices, and the admin page doesn’t display choices.
好的匾乓,我們已經(jīng)有Question的admin頁(yè)面了,但是一個(gè)Question有很多個(gè)Choices又谋,admin頁(yè)面也沒(méi)有展示這些choices拼缝。
Yet. There are two ways to solve this problem. The first is to register Choice with the admin just as we did with Question. That’s easy:
但是,我們有兩種方法來(lái)解決這個(gè)問(wèn)題彰亥。第一種方法是像Question一樣將Choice注冊(cè)到admin站點(diǎn)咧七,這非常簡(jiǎn)單:
polls/admin.py
from django.contrib import admin
from .models import Choice, Question
# ...
admin.site.register(Choice)
Now “Choices” is an available option in the Django admin. The “Add choice” form looks like this:
現(xiàn)在“Choices”已經(jīng)展示在Django admin站點(diǎn)了,“增加choice”表單看起來(lái)如下圖:
In that form, the “Question” field is a select box containing every question in the database. Django knows that a ForeignKey should be represented in the admin as a <select> box. In our case, only one question exists at this point.
在這個(gè)表單中任斋,“Question”字段是一個(gè)包含數(shù)據(jù)庫(kù)中所有Question的的單選框继阻。Django知道這是ForeignKey ,應(yīng)該在admin中作為單選框來(lái)展示废酷。在我們的例子中瘟檩,只有一個(gè)Question存在。
Also note the “Add Another” link next to “Question.” Every object with a ForeignKey relationship to another gets this for free. When you click “Add Another”, you’ll get a popup window with the “Add question” form. If you add a question in that window and click “Save”, Django will save the question to the database and dynamically add it as the selected choice on the “Add choice” form you’re looking at.
同時(shí)注意到Question附近的“增加另一個(gè)”的鏈接按鈕澈蟆。每個(gè)
ForeignKey 關(guān)系的對(duì)象都會(huì)自動(dòng)有這個(gè)按鈕墨辛。當(dāng)你點(diǎn)擊“Add Another”,會(huì)彈出一個(gè)“Add Question”表單趴俘。如果你通過(guò)那彈窗點(diǎn)擊save增加一個(gè)Question睹簇,Django會(huì)保存這個(gè)Question到數(shù)據(jù)庫(kù)并在 “Add choice”表單中增加一個(gè)可選項(xiàng)。
But, really, this is an inefficient way of adding Choice
objects to the system. It’d be better if you could add a bunch of Choices directly when you create the Question
object. Let’s make that happen.
但是寥闪,這真的不是增加Choice高效途徑太惠。當(dāng)你創(chuàng)建一個(gè)Question的時(shí)候,如果你能增加一打choices該多好疲憋。讓我們?cè)囋嚳础?/p>
Remove the register() call for the Choice model. Then, edit the Question registration code to read:
去掉register()調(diào)用Choice模型的代碼垛叨,然后編輯Question 的注冊(cè)代碼,如下:
polls/admin.py
from django.contrib import admin
from .models import Choice, Question
class ChoiceInline(admin.StackedInline):
model = Choice
extra = 3
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
inlines = [ChoiceInline]
admin.site.register(Question, QuestionAdmin)
This tells Django: “Choice objects are edited on the Question admin page. By default, provide enough fields for 3 choices.”
這告訴Django:“Choice對(duì)象可在Question的admin頁(yè)面編輯柜某。默認(rèn)情況下嗽元,有3個(gè)choices字段”
Load the “Add question” page to see how that looks:
訪問(wèn)“Add question” 頁(yè),看看它長(zhǎng)啥樣:
It works like this: There are three slots for related Choices – as specified by extra – and each time you come back to the “Change” page for an already-created object, you get another three extra slots.
它的工作原理如下:有3個(gè)表單組件關(guān)聯(lián)Choice對(duì)象喂击,而且當(dāng)你每次回到一個(gè)已存在對(duì)象的change頁(yè)面時(shí)剂癌,你又會(huì)看到三個(gè)新的表單組件
At the end of the three current slots you will find an “Add another Choice” link. If you click on it, a new slot will be added. If you want to remove the added slot, you can click on the X to the top right of the added slot. Note that you can’t remove the original three slots. This image shows an added slot:
在三個(gè)表單組件的最后,你可以看到“Add another Choice”鏈接翰绊,點(diǎn)擊它后佩谷,會(huì)創(chuàng)建一個(gè)新的表單選項(xiàng)旁壮。。如果你想移除已增加的槽谐檀,點(diǎn)擊右上角X即可抡谐。注意你不能去掉那三個(gè)原有的槽。下圖展示增加一個(gè)槽:
One small problem, though. It takes a lot of screen space to display all the fields for entering related Choice objects. For that reason, Django offers a tabular way of displaying inline related objects; you just need to change the ChoiceInline declaration to read:
然后桐猬,還有個(gè)小問(wèn)題麦撵。展示所有關(guān)聯(lián)的Choice對(duì)象會(huì)占據(jù)非常多的屏幕空間。為此溃肪,Django提供了一個(gè)扁平化的顯示方式免胃。你只需要將ChoiceInline 類(lèi)替換即可,如下:
polls/admin.py
class ChoiceInline(admin.TabularInline):
#...
Note that there is an extra “Delete?” column that allows removing rows added using the “Add Another Choice” button and rows that have already been saved.
注意有一個(gè) “Delete?”列惫撰,允許你刪除通過(guò)“Add Another Choice” 按鈕增加并保存的行羔沙。
Customize the admin change list?
Now that the Question admin page is looking good, let’s make some tweaks to the “change list” page – the one that displays all the questions in the system.
現(xiàn)在Question的admin頁(yè)面已經(jīng)非常漂亮了,我們繼續(xù)對(duì)“change list”做一下微調(diào)——就是那個(gè)展示所有Question列表的頁(yè)面
Here’s what it looks like at this point:
這就是它現(xiàn)在的樣子:
By default, Django displays the str()
of each object. But sometimes it’d be more helpful if we could display individual fields. To do that, use the list_display admin option, which is a tuple of field names to display, as columns, on the change list page for the object:
默認(rèn)情況下厨钻,Django調(diào)用str()展示每個(gè)對(duì)象扼雏。但是有時(shí)候,如果我們可以展示其他的字段的話夯膀,將會(huì)更好诗充。為此,你可以用list_display 選項(xiàng)棍郎,這是想要展示的字段名的集合,在change list頁(yè)面上將作為列來(lái)展示:
polls/admin.py
class QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ('question_text', 'pub_date')
Just for good measure, let’s also include the was_published_recently()
method from Tutorial 2:
更好的是银室,我們也可以展示was_published_recently()方法:
polls/admin.py
class QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ('question_text', 'pub_date', 'was_published_recently')
Now the question change list page looks like this:
現(xiàn)在Question的change list頁(yè)面看起來(lái)如下圖:
You can click on the column headers to sort by those values – except in the case of the was_published_recently header, because sorting by the output of an arbitrary method is not supported. Also note that the column header for was_published_recently is, by default, the name of the method (with underscores replaced with spaces), and that each line contains the string representation of the output.
你可以點(diǎn)擊列標(biāo)題來(lái)排序——除了was_published_recently外涂佃,因?yàn)閍rbitrary 方法的輸出并不支持排序。同時(shí)注意was_published_recently 列標(biāo)題蜈敢,默認(rèn)下是函數(shù)名(下劃線替換為了空格)辜荠,內(nèi)容則是輸出的字符串表示法。
You can improve that by giving that method (in polls/models.py) a few attributes, as follows:
你可以在polls/models.py中增加如下屬性來(lái)修復(fù)這個(gè)問(wèn)題:
polls/models.py
class Question(models.Model):
# ...
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
was_published_recently.admin_order_field = 'pub_date'
was_published_recently.boolean = True
was_published_recently.short_description = 'Published recently?'
For more information on these method properties, see list_display.
想了解跟多信息抓狭,請(qǐng)看 list_display.
Edit your polls/admin.py file again and add an improvement to the Question change list page: filters using thelist_filter. Add the following line to QuestionAdmin:
再次編輯polls/admin.py伯病,并進(jìn)一步改善Question change list頁(yè)面:用list_filter來(lái)作過(guò)濾器。在QuestionAdmin類(lèi)里加如下行:
list_filter = ['pub_date']
That adds a “Filter” sidebar that lets people filter the change list by the pub_date field:
這會(huì)增加一個(gè)過(guò)濾器面板否过,讓用戶可以通過(guò)pub_date 來(lái)過(guò)濾change list頁(yè)面:
The type of filter displayed depends on the type of field you’re filtering on. Because pub_date is a DateTimeField, Django knows to give appropriate filter options: “Any date”, “Today”, “Past 7 days”, “This month”, “This year”.
根據(jù)你選擇的過(guò)濾條件的不同午笛,Django會(huì)在面板中添加不容的過(guò)濾選項(xiàng)。由于pub_date是一個(gè)DateTimeField苗桂,因此药磺,Django自動(dòng)添加了這些選項(xiàng):“Any date”, “Today”, “Past 7 days”, “This month”, “This year”。
This is shaping up well. Let’s add some search capability:
為了做的更好煤伟。我們?cè)僭黾铀阉骺颍?/p>
search_fields = ['question_text']
That adds a search box at the top of the change list. When somebody enters search terms, Django will search the question_text field. You can use as many fields as you’d like – although because it uses a LIKE query behind the scenes, limiting the number of search fields to a reasonable number will make it easier for your database to do the search.
這會(huì)在頁(yè)面的頂部增加一個(gè)搜索框癌佩。當(dāng)輸入搜索關(guān)鍵字后木缝,Django會(huì)在question_text字段內(nèi)進(jìn)行搜索。只要你愿意围辙,你可以使用任意多個(gè)搜索字段我碟,Django在后臺(tái)使用的都是SQL查詢(xún)語(yǔ)句的LIKE語(yǔ)法,但是姚建,有限制的搜索字段有助于后臺(tái)的數(shù)據(jù)庫(kù)查詢(xún)效率矫俺。
Now’s also a good time to note that change lists give you free pagination. The default is to display 100 items per page. Change list pagination, search boxes, filters, date-hierarchies, and column-header-ordering all work together like you think they should.
現(xiàn)在你應(yīng)該注意到 了,change list有分頁(yè)功能桥胞,默認(rèn)下顯示100個(gè)每頁(yè)】沂兀現(xiàn)在,Change list pagination, search boxes, filters, date-hierarchies, and column-header-ordering等贩虾,都以你想的方式工作了催烘。
Customize the admin look and feel?
定制admin外觀?
Clearly, having “Django administration” at the top of each admin page is ridiculous. It’s just placeholder text.
很明顯,在每一個(gè)admin頁(yè)面頂端都顯示“Django administration”是很可笑的缎罢,它僅僅是個(gè)占位文本伊群。
That’s easy to change, though, using Django’s template system. The Django admin is powered by Django itself, and its interfaces use Django’s own template system.
利用Django的模板系統(tǒng),很容易修改它策精。Django的admin站點(diǎn)是由Django自己驅(qū)動(dòng)的舰始,用的也是Django自己的模板接口。
Customizing your project’s templates?
定制項(xiàng)目模板?
Create a templates directory in your project directory (the one that contains manage.py). Templates can live anywhere on your filesystem that Django can access. (Django runs as whatever user your server runs.) However, keeping your templates within the project is a good convention to follow.
在你的項(xiàng)目目錄(包含manage.py文件的目錄)下創(chuàng)建templates目錄咽袜。Templates可以放在任何Django可以訪問(wèn)到的地方丸卷。(你的服務(wù)以什么用戶跑,DJango就以什么用戶運(yùn)行)庵后询刹,將你的templates目錄放在project下是非常好的習(xí)慣谜嫉。
Open your settings file (mysite/settings.py
, remember) and add a DIRS option in the TEMPLATES setting:
打開(kāi)settings配置文件(mysite/settings.py, 記住 ),TEMPLATES 設(shè)置中增加 DIRS屬性
mysite/settings.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',
],
},
},
]
DIRS is a list of filesystem directories to check when loading Django templates; it’s a search path.
DIRS是一個(gè)文件系統(tǒng)目錄的列表凹联,當(dāng)加載Django模板時(shí)沐兰,會(huì)在DIRS中進(jìn)行查找。它是搜索路徑蔽挠。
Organizing templates
Just like the static files, we could have all our templates together, in one big templates directory, and it would work perfectly well. However, templates that belong to a particular application should be placed in that application’s template directory (e.g. polls/templates) rather than the project’s (templates). We’ll discuss in more detail in the reusable apps tutorial why we do this.
組織templates
就像靜態(tài)文件一樣住闯,我們可以把所有的模板都放在一起,形成一個(gè)大大的模板文件夾澳淑,并且工作正常比原。但是我們不建議這樣!我們建議每一個(gè)模板都應(yīng)該存放在它所屬應(yīng)用的模板目錄內(nèi)(例如polls/templates)而不是整個(gè)項(xiàng)目的模板目錄(templates)杠巡,因?yàn)檫@樣每個(gè)應(yīng)用才可以被方便和正確的重用春寿。請(qǐng)參考2.10節(jié)《如何重用apps》。
Now create a directory called admin inside templates, and copy the template admin/base_site.html from within the default Django admin template directory in the source code of Django itself (django/contrib/admin/templates) into that directory.
接下來(lái)忽孽,在剛才創(chuàng)建的templates中創(chuàng)建一個(gè)admin目錄绑改,將admin/base_site.html模板文件拷貝到該目錄內(nèi)谢床。這個(gè)html文件來(lái)自Django源碼,它位于django/contrib/admin/templates目錄內(nèi)厘线。
Where are the Django source files?
If you have difficulty finding where the Django source files are located on your system, run the following command:
如果你不知道Django的源代碼文件在哪识腿,運(yùn)行以下命令:
$ python -c "import django; print(django.__path__)"```
Then, just edit the file and replace{% raw %} {{ site_header|default:_('Django administration') }}{% endraw %} (including the curly braces) with your own site’s name as you see fit. You should end up with a section of code like:
編輯該文件,用你喜歡的站點(diǎn)名字替換掉{% raw %} {{ site_header|default:_('Django administration') }}{% endraw %}(包括兩個(gè)大括號(hào)一起)造壮,看起來(lái)像下面這樣:
{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
{% endblock %}
We use this approach to teach you how to override templates. In an actual project, you would probably use the [django.contrib.admin.AdminSite.site_header](https://docs.djangoproject.com/en/1.10/ref/contrib/admin/#django.contrib.admin.AdminSite.site_header) attribute to more easily make this particular customization.
在這里渡讼,我們使用這個(gè)方法教會(huì)你如何重寫(xiě)模板。但是在實(shí)際的項(xiàng)目中耳璧,你可以使用 [django.contrib.admin.AdminSite.site_header](https://docs.djangoproject.com/en/1.10/ref/contrib/admin/#django.contrib.admin.AdminSite.site_header)成箫,方便的對(duì)這個(gè)頁(yè)面title進(jìn)行自定義。
This template file contains lots of text like {% block branding %} and {{ title }}. The {%
and {{ tags are part of Django’s template language. When Django renders admin/base_site.html, this template language will be evaluated to produce the final HTML page, just like we saw in [Tutorial 3](https://docs.djangoproject.com/en/1.10/intro/tutorial03/).
這個(gè)模板文件包含了大量的如{% raw %}{% block branding %} and {{ title }}{% endraw %},{% raw %} {% and {{ {% endraw %}是Django的模板語(yǔ)言旨枯。當(dāng)Django渲染 admin/base_site.html文件時(shí)蹬昌,這些模板語(yǔ)言會(huì)生成最終的HTML頁(yè)面,就像[Tutorial 3](https://docs.djangoproject.com/en/1.10/intro/tutorial03/)所說(shuō)
Note that any of Django’s default admin templates can be overridden. To override a template, just do the same thing you did with base_site.html – copy it from the default directory into your custom directory, and make changes.
請(qǐng)注意攀隔,所有Django默認(rèn)的admin模板都可以被重寫(xiě)皂贩。類(lèi)似剛才重寫(xiě)base_site.html模板的方法一樣,從源代碼目錄將html文件拷貝至你自定義的目錄內(nèi)昆汹,然后修改文件明刷。
#### **Customizing your *application’s* templates[?](https://docs.djangoproject.com/en/1.10/intro/tutorial07/#customizing-your-application-s-templates)**
#### **定制 *application’s* 模板[?](https://docs.djangoproject.com/en/1.10/intro/tutorial07/#customizing-your-application-s-templates)**
Astute readers will ask: But if [DIRS](https://docs.djangoproject.com/en/1.10/ref/settings/#std:setting-TEMPLATES-DIRS) was empty by default, how was Django finding the default admin templates? The answer is that, since [APP_DIRS](https://docs.djangoproject.com/en/1.10/ref/settings/#std:setting-TEMPLATES-APP_DIRS) is set to True, Django automatically looks for a templates/ subdirectory within each application package, for use as a fallback (don’t forget that django.contrib.admin is an application).
聰明的讀者可能會(huì)問(wèn):但是DIRS默認(rèn)是空的,Django是如何找到默認(rèn)的admin模板呢满粗?回答是辈末,由于APP_DIRS被設(shè)置為T(mén)rue,Django將自動(dòng)查找每一個(gè)應(yīng)用包內(nèi)的templates/子目錄(不要忘了django.contrib.admin也是一個(gè)應(yīng)用)映皆。
Our poll application is not very complex and doesn’t need custom admin templates. But if it grew more sophisticated and required modification of Django’s standard admin templates for some of its functionality, it would be more sensible to modify the *application’s* templates, rather than those in the *project*. That way, you could include the polls application in any new project and be assured that it would find the custom templates it needed.
我們的投票應(yīng)用不太復(fù)雜挤聘,因此不需要自定義admin模板。但是如果它變得越來(lái)越復(fù)雜劫扒,因?yàn)槟承┕δ芏枰薷腄jango的標(biāo)準(zhǔn)admin模板檬洞,那么修改app的模板就比修改項(xiàng)目的模板更加明智狸膏。這樣的話沟饥,你可以將投票應(yīng)用加入到任何新的項(xiàng)目中,并且保證能夠找到它所需要的自定義模板湾戳。
See the [template loading documentation](https://docs.djangoproject.com/en/1.10/topics/templates/#template-loading) for more information about how Django finds its templates.
查看[template loading documentation](https://docs.djangoproject.com/en/1.10/topics/templates/#template-loading)獲取更多關(guān)于Django如何查找模板的信息贤旷。
#### **Customize the admin index page[?](https://docs.djangoproject.com/en/1.10/intro/tutorial07/#customize-the-admin-index-page)**
#### **定制admin 首頁(yè)[?](https://docs.djangoproject.com/en/1.10/intro/tutorial07/#customize-the-admin-index-page)**
On a similar note, you might want to customize the look and feel of the Django admin index page.
很多人都會(huì)想定制化Django admin的首頁(yè)的外觀和感覺(jué)。
By default, it displays all the apps in [INSTALLED_APPS](https://docs.djangoproject.com/en/1.10/ref/settings/#std:setting-INSTALLED_APPS) that have been registered with the admin application, in alphabetical order. You may want to make significant changes to the layout. After all, the index is probably the most important page of the admin, and it should be easy to use.
默認(rèn)情況下砾脑,首頁(yè)展示所有[INSTALLED_APPS](https://docs.djangoproject.com/en/1.10/ref/settings/#std:setting-INSTALLED_APPS) 中被注冊(cè)到admin的應(yīng)用幼驶,你或許想改變一下布局。畢竟韧衣,首頁(yè)是admin站點(diǎn)最重要的頁(yè)面盅藻,它應(yīng)該要簡(jiǎn)單易用购桑。
The template to customize is admin/index.html. (Do the same as with admin/base_site.html in the previous section – copy it from the default directory to your custom template directory). Edit the file, and you’ll see it uses a template variable called app_list. That variable contains every installed Django app. Instead of using that, you can hard-code links to object-specific admin pages in whatever way you think is best.
要定制的模板是admin/index.html,(像上節(jié)中更改admin/base_site.html模板一樣氏淑,從它默認(rèn)的目錄拷貝到你的定制化模板目錄)勃蜘。編輯文件,你會(huì)看到模板有一個(gè)app_list的變量假残。你可以硬編碼鏈接到指定對(duì)象的admin頁(yè)面缭贡,使用任何你認(rèn)為好的方法,用于替代這個(gè)app_list辉懒。
#### **What’s next?[?](https://docs.djangoproject.com/en/1.10/intro/tutorial07/#what-s-next)**
#### **接下來(lái)學(xué)習(xí)什么?[?](https://docs.djangoproject.com/en/1.10/intro/tutorial07/#what-s-next)**
The beginner tutorial ends here. In the meantime, you might want to check out some pointers on [where to go from here](https://docs.djangoproject.com/en/1.10/intro/whatsnext/).
入門(mén)教程到這里就結(jié)束了阳惹。此時(shí),你應(yīng)該轉(zhuǎn)到 [where to go from here](https://docs.djangoproject.com/en/1.10/intro/whatsnext/)看看接下該學(xué)習(xí)什么
If you are familiar with Python packaging and interested in learning how to turn polls into a “reusable app”, check out [Advanced tutorial: How to write reusable apps](https://docs.djangoproject.com/en/1.10/intro/reusable-apps/).
或者你對(duì)Python包機(jī)制很熟悉眶俩,對(duì)如何將投票應(yīng)用轉(zhuǎn)換成一個(gè)可重用的app感興趣莹汤,請(qǐng)看[Advanced tutorial: How to write reusable apps](https://docs.djangoproject.com/en/1.10/intro/reusable-apps/).