Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit08fe98c

Browse files
committed
Add Dependency Inversion
1 parent64ee320 commit08fe98c

File tree

1 file changed

+90
-1
lines changed

1 file changed

+90
-1
lines changed

‎README.md‎

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1302,7 +1302,96 @@ def view(request):
13021302

13031303
###**Dependency Inversion Principle (DIP)**
13041304

1305-
*Coming soon*
1305+
>“Depend upon abstractions, not concrete details”,
1306+
>Uncle Bob.
1307+
1308+
Imagine we wanted to write a web view that returns an HTTP response that
1309+
streams rows of a CSV file we create on the fly. We want to use the CSV writer
1310+
that is provided by the standard library.
1311+
1312+
**Bad**
1313+
```python
1314+
import csv
1315+
from ioimport StringIO
1316+
1317+
1318+
classStreamingHttpResponse:
1319+
"""A streaming HTTP response"""
1320+
...# implementation code goes here
1321+
1322+
1323+
defsome_view(request):
1324+
rows= (
1325+
['First row','Foo','Bar','Baz'],
1326+
['Second row','A','B','C','"Testing"',"Here's a quote"]
1327+
)
1328+
# Define a generator to stream data directly to the client
1329+
defstream():
1330+
buffer_= StringIO()
1331+
writer= csv.writer(buffer_,delimiter=';',quotechar='"')
1332+
for rowin rows:
1333+
writer.writerow(row)
1334+
buffer_.seek(0)
1335+
data= buffer_.read()
1336+
buffer_.seek(0)
1337+
buffer_.truncate()
1338+
yield data
1339+
1340+
# Create the streaming response object with the appropriate CSV header.
1341+
response= StreamingHttpResponse(stream(),content_type='text/csv')
1342+
response['Content-Disposition']='attachment; filename="somefilename.csv"'
1343+
1344+
return response
1345+
1346+
```
1347+
1348+
Our first implementation works around the CSV's writer interface by manipulating
1349+
a`StringIO` object (which is file-like) and performing several low level
1350+
operations in order to farm out the rows from the writer. It's a lot of work
1351+
and not very elegant.
1352+
1353+
A better way is to leverage the fact that the writer just needs an object with
1354+
a`.write()` method to do our bidding. Why not pass it a dummy object that
1355+
immediately returns the newly assembled row, so that the`StreamingHttpResponse`
1356+
class can immediate stream it back to the client?
1357+
1358+
**Good**
1359+
```python
1360+
import csv
1361+
1362+
1363+
classEcho:
1364+
"""An object that implements just the write method of the file-like
1365+
interface.
1366+
"""
1367+
defwrite(self,value):
1368+
"""Write the value by returning it, instead of storing in a buffer."""
1369+
return value
1370+
1371+
defsome_streaming_csv_view(request):
1372+
"""A view that streams a large CSV file."""
1373+
rows= (
1374+
['First row','Foo','Bar','Baz'],
1375+
['Second row','A','B','C','"Testing"',"Here's a quote"]
1376+
)
1377+
writer= csv.writer(Echo(),delimiter=';',quotechar='"')
1378+
return StreamingHttpResponse(
1379+
(writer.writerow(row)for rowin rows),
1380+
content_type="text/csv",
1381+
headers={'Content-Disposition':'attachment; filename="somefilename.csv"'},
1382+
)
1383+
1384+
```
1385+
1386+
Much better, and it works like a charm! The reason it's superior to the previous
1387+
implementation should be obvious: less code (and more performant) to achieve
1388+
the same result. We decided to leverage the fact that the writer class depends
1389+
on the`.write()` abstraction of the object it receives, without caring about
1390+
the low level, concrete details of what the method actually does.
1391+
1392+
This example was taken from
1393+
[a submission made to the Django documentation](https://code.djangoproject.com/ticket/21179)
1394+
by this author.
13061395

13071396
**[⬆ back to top](#table-of-contents)**
13081397

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp