Skip to content

Commit 6360be7

Browse files
committed
Chapters 12-19 and an updated version of plugin
1 parent 8e6475a commit 6360be7

File tree

9 files changed

+156
-89
lines changed

9 files changed

+156
-89
lines changed

book.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
1010
1111
12-
12+
1313
],
1414
"pluginsConfig": {
1515
"ga": {

en/css/README.md

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ It was written by programmers who worked for Twitter and is now developed by vol
1616

1717
## Install Bootstrap
1818

19-
To install Bootstrap, you need to add this to your `<head>` in your `.html` file (`blog/templates/blog/post_list.html`):
19+
To install Bootstrap, you need to add this to your `<head>` in your `.html` file:
2020

21-
```html
21+
```html:blog/templates/blog/post_list.html
2222
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
2323
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
2424
```
@@ -38,15 +38,17 @@ Finally we will take a closer look at these things we've been calling __static f
3838

3939
### Where to put static files for Django
4040

41-
As you saw when we ran `collectstatic` on the server, Django already knows where to find the static files for the built-in "admin" app. Now we just need to add some static files for our own app, `blog`.
41+
As you saw when we ran `collectstatic` on the server, Django already knows where to find the static files for the built-in "admin" app. Now we just need to add some static files for our own app, `blog`.
4242

4343
We do that by creating a folder called `static` inside the blog app:
4444

45+
```
4546
djangogirls
4647
├── blog
4748
│ ├── migrations
4849
│ └── static
4950
└── mysite
51+
```
5052

5153
Django will automatically find any folders called "static" inside any of your apps' folders, and it will be able to use their contents as static files.
5254

@@ -56,11 +58,13 @@ Django will automatically find any folders called "static" inside any of your ap
5658

5759
Let's create a CSS file now, to add your own style to your web-page. Create a new directory called `css` inside your `static` directory. Then create a new file called `blog.css` inside this `css` directory. Ready?
5860

61+
```
5962
djangogirls
6063
└─── blog
6164
└─── static
6265
└─── css
6366
└─── blog.css
67+
```
6468

6569
Time to write some CSS! Open up the `blog/static/css/blog.css` file in your code editor.
6670

@@ -70,7 +74,7 @@ But let's do at least a little. Maybe we could change the color of our header? T
7074

7175
In your `blog/static/css/blog.css` file you should add the following code:
7276

73-
```css
77+
```css:blog/static/css/blog.css
7478
h1 a {
7579
color: #FCA205;
7680
}
@@ -88,21 +92,21 @@ Read about [CSS Selectors in w3schools](http://www.w3schools.com/cssref/css_sele
8892

8993
Then, we need to also tell our HTML template that we added some CSS. Open the `blog/templates/blog/post_list.html` file and add this line at the very beginning of it:
9094

91-
```html
95+
```html:blog/templates/blog/post_list.html
9296
{% load staticfiles %}
9397
```
9498

9599
We're just loading static files here :). Then, between the `<head>` and `</head>`, after the links to the Bootstrap CSS files (the browser reads the files in the order they're given, so code in our file may override code in Bootstrap files), add this line:
96100

97-
```html
101+
```html:blog/templates/blog/post_list.html
98102
<link rel="stylesheet" href="{% static 'css/blog.css' %}">
99103
```
100104

101105
We just told our template where our CSS file is located.
102106

103107
Your file should now look like this:
104108

105-
```html
109+
```html:blog/templates/blog/post_list.html
106110
{% load staticfiles %}
107111
<html>
108112
<head>
@@ -133,7 +137,7 @@ OK, save the file and refresh the site!
133137

134138
Nice work! Maybe we would also like to give our website a little air and increase the margin on the left side? Let's try this!
135139

136-
```css
140+
```css:blog/static/css/blog.css
137141
body {
138142
padding-left: 15px;
139143
}
@@ -145,15 +149,15 @@ Add this to your CSS, save the file and see how it works!
145149

146150
Maybe we can customize the font in our header? Paste this into your `<head>` in `blog/templates/blog/post_list.html` file:
147151

148-
```html
152+
```html:blog/templates/blog/post_list.html
149153
<link href="http://fonts.googleapis.com/css?family=Lobster&subset=latin,latin-ext" rel="stylesheet" type="text/css">
150154
```
151155

152156
This line will import a font called *Lobster* from Google Fonts (https://www.google.com/fonts).
153157

154158
Now add the line `font-family: 'Lobster';` in the CSS file `blog/static/css/blog.css` inside the `h1 a` declaration block (the code between the braces `{` and `}`) and refresh the page:
155159

156-
```css
160+
```css:blog/static/css/blog.css
157161
h1 a {
158162
color: #FCA205;
159163
font-family: 'Lobster';
@@ -169,15 +173,15 @@ As mentioned above, CSS has a concept of classes, which basically allows you to
169173

170174
Go ahead and name some parts of the HTML code. Add a class called `page-header` to your `div` that contains your header, like this:
171175

172-
```html
176+
```html:blog/templates/blog/post_list.html
173177
<div class="page-header">
174178
<h1><a href="/">Django Girls Blog</a></h1>
175179
</div>
176180
```
177181

178182
And now add a class `post` to your `div` containing a blog post.
179183

180-
```html
184+
```html:blog/templates/blog/post_list.html
181185
<div class="post">
182186
<p>published: {{ post.published_date }}</p>
183187
<h1><a href="">{{ post.title }}</a></h1>
@@ -187,7 +191,7 @@ And now add a class `post` to your `div` containing a blog post.
187191

188192
We will now add declaration blocks to different selectors. Selectors starting with `.` relate to classes. There are many great tutorials and explanations about CSS on the Web to help you understand the following code. For now, just copy and paste it into your `blog/static/css/blog.css` file:
189193

190-
```css
194+
```css:blog/static/css/blog.css
191195
.page-header {
192196
background-color: #ff9400;
193197
margin-top: 0;
@@ -239,7 +243,7 @@ h1, h2, h3, h4 {
239243

240244
Then surround the HTML code which displays the posts with declarations of classes. Replace this:
241245

242-
```html
246+
```html:blog/templates/blog/post_list.html
243247
{% for post in posts %}
244248
<div class="post">
245249
<p>published: {{ post.published_date }}</p>
@@ -251,7 +255,7 @@ Then surround the HTML code which displays the posts with declarations of classe
251255

252256
in the `blog/templates/blog/post_list.html` with this:
253257

254-
```html
258+
```html:blog/templates/blog/post_list.html
255259
<div class="content container">
256260
<div class="row">
257261
<div class="col-md-8">

en/django_orm/README.md

Lines changed: 76 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@ It's easiest to learn by example. Let's try this, shall we?
1414

1515
Open up your local console (not on PythonAnywhere) and type this command:
1616

17-
(myvenv) ~/djangogirls$ python manage.py shell
17+
```:command-line
18+
(myvenv) ~/djangogirls$ python manage.py shell
19+
```
1820

1921
The effect should be like this:
2022

21-
(InteractiveConsole)
22-
>>>
23+
```python:command-line
24+
(InteractiveConsole)
25+
>>>
26+
```
2327

2428
You're now in Django's interactive console. It's just like Python prompt but with some additional Django magic :). You can use all the Python commands here too, of course.
2529

@@ -28,19 +32,25 @@ You're now in Django's interactive console. It's just like Python prompt but wit
2832

2933
Let's try to display all of our posts first. You can do that with the following command:
3034

31-
>>> Post.objects.all()
32-
Traceback (most recent call last):
33-
File "<console>", line 1, in <module>
34-
NameError: name 'Post' is not defined
35+
```python:command-line
36+
>>> Post.objects.all()
37+
Traceback (most recent call last):
38+
File "<console>", line 1, in <module>
39+
NameError: name 'Post' is not defined
40+
```
3541

3642
Oops! An error showed up. It tells us that there is no Post. It's correct -- we forgot to import it first!
3743

38-
>>> from blog.models import Post
44+
```python:command-line
45+
>>> from blog.models import Post
46+
```
3947

4048
This is simple: we import model `Post` from `blog.models`. Let's try displaying all posts again:
4149

42-
>>> Post.objects.all()
43-
[<Post: my post title>, <Post: another post title>]
50+
```python:command-line
51+
>>> Post.objects.all()
52+
[<Post: my post title>, <Post: another post title>]
53+
```
4454

4555
It's a list of the posts we created earlier! We created these posts using the Django admin interface. However, now we want to create new posts using Python, so how do we do that?
4656

@@ -49,33 +59,45 @@ It's a list of the posts we created earlier! We created these posts using the Dj
4959

5060
This is how you create a new Post object in database:
5161

52-
>>> Post.objects.create(author=me, title='Sample title', text='Test')
62+
```python:command-line
63+
>>> Post.objects.create(author=me, title='Sample title', text='Test')
64+
```
5365

5466
But we have one missing ingredient here: `me`. We need to pass an instance of `User` model as an author. How to do that?
5567

5668
Let's import User model first:
5769

58-
>>> from django.contrib.auth.models import User
70+
```python:command-line
71+
>>> from django.contrib.auth.models import User
72+
```
5973

6074
What users do we have in our database? Try this:
6175

62-
>>> User.objects.all()
63-
[<User: ola>]
76+
```python:command-line
77+
>>> User.objects.all()
78+
[<User: ola>]
79+
```
6480

6581
It's the superuser we created earlier! Let's get an instance of the user now:
6682

67-
me = User.objects.get(username='ola')
83+
```python:command-line
84+
me = User.objects.get(username='ola')
85+
```
6886

6987
As you can see, we now `get` a `User` with a `username` that equals to 'ola'. Neat! Of course, you have to adjust it to your username.
7088

7189
Now we can finally create our post:
7290

73-
>>> Post.objects.create(author=me, title='Sample title', text='Test')
91+
```python:command-line
92+
>>> Post.objects.create(author=me, title='Sample title', text='Test')
93+
```
7494

7595
Hurray! Wanna check if it worked?
7696

77-
>>> Post.objects.all()
78-
[<Post: my post title>, <Post: another post title>, <Post: Sample title>]
97+
```python:command-line
98+
>>> Post.objects.all()
99+
[<Post: my post title>, <Post: another post title>, <Post: Sample title>]
100+
```
79101

80102
There it is, one more post in the list!
81103

@@ -89,46 +111,63 @@ You can now have a little fun and add more posts to see how it works. Add 2-3 mo
89111

90112
A big part of QuerySets is an ability to filter them. Let's say, we want to find all posts that are authored by User ola. We will use `filter` instead of `all` in `Post.objects.all()`. In parentheses we will state what condition(s) needs to be met by a blog post to end up in our queryset. In our situation it is `author` that is equal to `me`. The way to write it in Django is: `author=me`. Now our piece of code looks like this:
91113

92-
>>> Post.objects.filter(author=me)
93-
[<Post: Sample title>, <Post: Post number 2>, <Post: My 3rd post!>, <Post: 4th title of post>]
114+
```python:command-line
115+
>>> Post.objects.filter(author=me)
116+
[<Post: Sample title>, <Post: Post number 2>, <Post: My 3rd post!>, <Post: 4th title of post>]
117+
```
94118

95119
Or maybe we want to see all the posts that contain a word 'title' in the `title` field?
96120

97-
>>> Post.objects.filter(title__contains='title')
98-
[<Post: Sample title>, <Post: 4th title of post>]
121+
```python:command-line
122+
>>> Post.objects.filter(title__contains='title')
123+
[<Post: Sample title>, <Post: 4th title of post>]
124+
```
99125

100126
> **Note** There are two underscore characters (`_`) between `title` and `contains`. Django's ORM uses this syntax to separate field names ("title") and operations or filters ("contains"). If you only use one underscore, you'll get an error like "FieldError: Cannot resolve keyword title_contains".
101127
102128
You can also get a list of all published posts. We do it by filtering all the posts that have `published_date` set in the past:
103-
>>> from django.utils import timezone
104-
>>> Post.objects.filter(published_date__lte=timezone.now())
105-
[]
129+
130+
```python:command-line
131+
>>> from django.utils import timezone
132+
>>> Post.objects.filter(published_date__lte=timezone.now())
133+
[]
134+
```
106135

107136
Unfortunately, the post we added from the Python console is not published yet. We can change that! First get an instance of a post we want to publish:
108137

109-
>>> post = Post.objects.get(title="Sample title")
138+
```python:command-line
139+
>>> post = Post.objects.get(title="Sample title")
140+
```
110141

111142
And then publish it with our `publish` method!
112143

113-
>>> post.publish()
144+
```python:command-line
145+
>>> post.publish()
146+
```
114147

115148
Now try to get list of published posts again (press the up arrow button 3 times and hit `enter`):
116149

117-
>>> Post.objects.filter(published_date__lte=timezone.now())
118-
[<Post: Sample title>]
150+
```python:command-line
151+
>>> Post.objects.filter(published_date__lte=timezone.now())
152+
[<Post: Sample title>]
153+
```
119154

120155

121156
### Ordering objects
122157

123158
QuerySets also allow you to order the list of objects. Let's try to order them by `created_date` field:
124159

125-
>>> Post.objects.order_by('created_date')
126-
[<Post: Sample title>, <Post: Post number 2>, <Post: My 3rd post!>, <Post: 4th title of post>]
160+
```python:command-line
161+
>>> Post.objects.order_by('created_date')
162+
[<Post: Sample title>, <Post: Post number 2>, <Post: My 3rd post!>, <Post: 4th title of post>]
163+
```
127164

128165
We can also reverse the ordering by adding `-` at the beginning:
129166

130-
>>> Post.objects.order_by('-created_date')
131-
[<Post: 4th title of post>, <Post: My 3rd post!>, <Post: Post number 2>, <Post: Sample title>]
167+
```python:command-line
168+
>>> Post.objects.order_by('-created_date')
169+
[<Post: 4th title of post>, <Post: My 3rd post!>, <Post: Post number 2>, <Post: Sample title>]
170+
```
132171

133172

134173
### Chaining QuerySets
@@ -141,5 +180,7 @@ This is really powerful and lets you write quite complex queries.
141180

142181
Cool! You're now ready for the next part! To close the shell, type this:
143182

144-
>>> exit()
145-
$
183+
```python:command-line
184+
>>> exit()
185+
$
186+
```

0 commit comments

Comments
 (0)