django --version=1.11.5
Part1:
-
ulrs.py include()
- After adding the app/urls.py , add an import for django.conf.urls.include and insert an include ( ) in the urlpatterns .
- The idea behind include() is to make it easy to plug-and-play URLs. Since polls are in their own URLconf (polls/urls.py), they can be placed under “/polls/”, or under “/fun_polls/”, or under “/content/polls/”, or any other path root, and the app will still work.
- Should always use include() when you include other URL patterns. admin.site.urls is the only exception to this.
Part2:
-
Three-steps to making sql changes
- Change your models (in models.py).
- Run python manage.py makemigrations to create migrations for those changes
- Run python manage.py migrate to apply those changes to the database.
- !!! Before the three-steps , make sure tell the project that the app in installed . You need to configurate class in the INSTALLED_APPS setting.
-
Attention different field types
-
ForeignKey
- Display any models from the related object set (ForeignKey)
>>> q = Question.objects.get(pk=1) >>> q.choice_set.all() <QuerySet []>
- Display any models from the related object set (ForeignKey)
-
Django using two underline to select
-
eg:
>>> from django.utils import timezone. >>> current_year = timezone.now().year >>> Question.objects.get(pub_date__year=current_year)
from django.utils import timezone
-
The timezone in django is like the datetime model in python.
eg:>>> from django.utils import timezone >>> timezone.now() >>> datetime.datetime(2017, 11, 13, 1, 29, 43, 980029, tzinfo=<UTC>)
-
-
Register app in admin
- Tell the admin that Question objects have an admin interface.
polls/admin.py from django.contrib import admin +from .models import Question,Choice +admin.site.register(Question) +admin.site.register(Choice) ###注意单独的models.class.register都应另起一行
- Tell the admin that Question objects have an admin interface.
Part 3:
-
Template namespacing
- Django will choose the first template it finds whose name matches, and if you had a template with the same name in a different application, Django would be unable to distinguish between them.So the easiest way to ensure this is by namespacing them. That is, by putting those templates inside another directory named for the application itself.
eg:polls(app)/templates/polls/index.html - APP_DIRS:Default: False , Whether the engine should look for template source files inside installed applications. The default settings.py file created by django-admin startproject sets 'APP_DIRS': True.Django automatically looks for a templates/ subdirectory within each application package.
- Django will choose the first template it finds whose name matches, and if you had a template with the same name in a different application, Django would be unable to distinguish between them.So the easiest way to ensure this is by namespacing them. That is, by putting those templates inside another directory named for the application itself.
-
render()
- The render() function takes the request object as its first argument, a template name as its second argument and a dictionary as its optional third argument. It returns an HttpResponse object of the given template rendered with the given context.
-
get_object_or_404()
-
The get_object_or_404() function takes a Django model as its first argument and an arbitrary number of keyword arguments, which it passes to the get() function of the model’s manager. It raises Http404 if the object doesn’t exist.
def detail(request, question_id): question=get_object_or_404(Question, pk=question_id) return render(request, 'polls/detail.html', {'question': question})
Why do we use a helper function get_object_or_404() ? Because that would couple the model layer to the view layer. One of the foremost design goals of Django is to maintain loose coupling. Some controlled coupling is introduced in the django.shortcuts module.
-
-
get_list_or_404()
- which works just as get_object_or_404 ( ) – except using filter() instead of get(). It raises Http404 if the list is empty.
def my_view(request): my_objects = get_list_or_404(MyModel, published=True) ##This example is equivalent to: def my_view(request): my_objects = list(MyModel.objects.filter(published=True)) if not my_objects: raise Http404("No MyModel matches the given query.")
- which works just as get_object_or_404 ( ) – except using filter() instead of get(). It raises Http404 if the list is empty.
-
Removing hardcodeed URLs in templates
- Since you defined the name argument in the app/urls.py in the polls.urls module, you can remove a reliance on specific URL paths defined in your url configurations by using the {% url %}template tag , that is easy to change URLs on projects with a lot of templates.
##Before change: <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li> ##After change: <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
- Since you defined the name argument in the app/urls.py in the polls.urls module, you can remove a reliance on specific URL paths defined in your url configurations by using the {% url %}template tag , that is easy to change URLs on projects with a lot of templates.
-
app_name
- Add namespaces to your URLconf , so that Django knows which app view to create for a url when using the {% url %} template tag
##polls/urls.py app_name = 'polls' urlpatterns = [ ... ] !!Also you need change your templates like: ##polls/templates/polls/index.html <li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
- Add namespaces to your URLconf , so that Django knows which app view to create for a url when using the {% url %} template tag
Part 4:
-
Cross Site Request Forgeries
- All POST forms that are targeted at internal URLs should use the % csrf_token %} template tag.
-
request.POST
-
request.POST is a dictionary-like object that lets you access submitted data by key name. In this case, request.POST['choice'] returns the ID of the selected choice, as a string. request.POST values are always strings.
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): . .. ...
-
request.POST is a dictionary-like object that lets you access submitted data by key name. In this case, request.POST['choice'] returns the ID of the selected choice, as a string. request.POST values are always strings.
-
HttpResponseRedirect
- As the Python comment above points out, you should always return an HttpResponseRedirect after successfully dealing with POST data.HttpResponseRedirect takes a single argument: the URL to which the user will be redirected
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
- As the Python comment above points out, you should always return an HttpResponseRedirect after successfully dealing with POST data.HttpResponseRedirect takes a single argument: the URL to which the user will be redirected
-
reverse()
- This function helps avoid having to hardcode a URL in the view function. It is given the name of the view that we want to pass control to and the variable portion of the URL pattern that points to that view.
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
- This function helps avoid having to hardcode a URL in the view function. It is given the name of the view that we want to pass control to and the variable portion of the URL pattern that points to that view.
-
Simple generic views
- If you’re only changing a few simple attributes on a class-based view, you can simply pass them into the as_view() method call itself:
from django.conf.urls import url from django.views.generic import TemplateView urlpatterns = [ url(r'^about/$', TemplateView.as_view(template_name="about.html")), ]
- If you’re only changing a few simple attributes on a class-based view, you can simply pass them into the as_view() method call itself:
-
Subclassing generic views
- More powerful way to use generic views is to inherit from an existing view and override attributes (such as the template_name) or methods (such as get_context_data) in your subclass to provide new values or methods.
# some_app/views.py from django.views.generic import T TemplateView class AboutView(TemplateView): template_name = "about.html" ---------------------------------------------------- # urls.py from django.conf.urls import url from some_app.views import AboutView urlpatterns = [ url(r'^about/$', AboutView.as_view()),
- More powerful way to use generic views is to inherit from an existing view and override attributes (such as the template_name) or methods (such as get_context_data) in your subclass to provide new values or methods.
-
Built-in class-based generic views
- Django’s generic views were developed to ease that pain. They take certain common idioms and patterns found in view development and abstract them so that you can quickly write common views of data without having to write too much code.
- See the documents
Part 5:
-
Create a test
- A conventional place for an application’s tests is in the application’s tests.py file; the testing system will automatically find tests in any file whose name begins with test.
import datetime from django.utils import timezone from django.test import TestCase from .models import Question class QuestionModelTests(TestCase): def test_was_published_recently_with_future_question(self): """ was_published_recently() returns False for questions whose pub_date is in the future. """ time = timezone.now() + datetime.timedelta(days=30) future_question = Question(pub_date=time) self.assertIs(future_question.was_published_recently(), False)
- A conventional place for an application’s tests is in the application’s tests.py file; the testing system will automatically find tests in any file whose name begins with test.
-
Good rules-of-thumb include having:
- a separate TestClass for each model or view
- a separate test method for each set of conditions you want to test
- test method names that describe their function
Part 7:
-
Customize the admin look and feel
Part 7