锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 鎵撳紑settings.py錛屽湪database鑺傜偣涓嬶細 ENGINE 鏁版嵁搴撳紩鎿庡悕縐幫紝鍙互鏄?/span>'django.db.backends.postgresql_psycopg2'鎴?
'django.db.backends.mysql' 鎴?
'django.db.backends.sqlite3' NAME 鏁版嵁搴撳悕縐幫紝 濡傛灉浣跨敤sqlite錛岃繖閲屽氨鏄痙b鏂囦歡緇濆璺緞錛屾瘮濡俧:/temp/mysite/data.db USER 鏁版嵁搴撶敤鎴峰悕錛宻qlite涓嶉渶瑕?/p>
PASSWORD 瀵嗙爜錛宻qlite涓嶉渶瑕?/p>
HOST 鏁版嵁搴撲富鏈篿p錛宻qlite涓嶉渶瑕?/p>
寤鴻浣跨敤sqlite銆傚鏋滀嬌鐢ㄥ叾浠栧PostgerSQL銆丮ySQL絳夛紝鍦ㄩ厤緗箣鍓嶈紜繚鍏堝湪鏁版嵁搴撲腑宸插緩绔嬬浉鍏抽」鐩?br />
Powered by ScribeFire. Powered by ScribeFire. There are lots of gems buried in Django that are slowly coming to light. Generic views and specifically the CRUD (create, update, delete) generic views are extremely powerful but underdocumented. This brief tutorial will show you how to make use of CRUD generic views in your Django application. One of my first encounters with Rails was the simple todo list tutorial which managed to relate lots of useful information by creating a simple yet useful application. While I will do my best to point out interesting and useful things along the way, it is probably best that you be familiar with the official Django tutorials. Now would also probably be a good time to mention that this tutorial works for me using MySQL and revision 524. Django is under constant development, so things may change. I鈥檒l do my best to keep up with changes. As with all Django projects, the best place to start is to start with Now that we have the project set up, let鈥檚 take a look at our rather simple model (
The model is short and sweet, storing a title, description, two dates, and if the task is done or not. To play with your model in the admin, add the following to Feel free to play around with your model using the admin site. For details, see tutorial 2. Now let鈥檚 configure our URLs. We鈥檒l fill in the code behind these URLs as we go. I edited
Note: I had to alter the formatting of the urlpatterns in order to make them fit. It looks a lot better in its original formatting. We use the Let鈥檚 look at each of these URLs one at a time, along with the code behind them.
This points to our index view, which is an index function in
This view creates two lists for us to work with in our template, Make sure that you have a template directory defined in todo.settings.main (this refers to
Now let鈥檚 take a look at the template that I鈥檓 using for the index:
Don鈥檛 let this index scare you, it鈥檚 just a little bit of logic, a little looping, and some links to other parts of the application. See the template authoring guide if you have questions. Here鈥檚 a picture to give you a better idea as to how the above barebones template renders in Firefox: Now let鈥檚 take a look at the following URL pattern:
There鈥檚 a lot of magic going on here that鈥檚 going to make your life really easy. First off, we鈥檙e going to call the Here鈥檚 the template that I am using for
Here鈥檚 what the create template looks like rendered: If we fill out the form without the proper (or correctly formatted) information, we鈥檒l get an error:
This URL pattern handles updates. The beautiful thing is it sends requests to
So if there鈥檚 no object present, we鈥檙e creating. If there鈥檚 an object present, we鈥檙e updating. Same form. Pretty cool.
Warning: It looks like form.create_date_date and form.create_date_time have broken between the time I wrote this and wrote it up. This form will not prepopulate the form with the stored information. There鈥檚 a ticket for this, and I鈥檒l update as neccesary when it has been fixed. Here鈥檚 the URL pattern to delte a task:
There鈥檚 another little Django gem in the delete function. If we end up at
Once this form is submitted, the actual delete takes place and we are redirected to the main index page (because we set That pretty much covers the basics of the CRUD generic views. The great thing about generic views is that you can use them along side your custom views. There鈥檚 no need to do a ton of custom programming for list/detail, date-based, or CRUD since those generic views are available to you. Because we set up our URL patterns, we can make sure that we craft URLs that look pretty and make sense. For my sample tasks application I decided that I wanted to create links that would immediately set a task as complete and then redirect to the index. This is pretty much trivial and can be accomplished by adding the following URL pattern and backing it up with the appropriate view. Here鈥檚 the pattern:
And here鈥檚 the view that goes along with it (from
I do plan to actually handle errors and respond accordingly, but it was late last night and I just wanted to see it work (and it does). Django rocks. Generic views rock. The framework and specifically the generic views make your life easy. My little tasks app took a few hours to put together, but a significant portion of that was reading up on the documentation, trying to figure out generic views using the existing docs and reading the source, and of course pestering the DjangoMasters about generic views and other stuff on #django (thanks all). I hope this overview of CRUD generic views helps, but if anything confuses you, don鈥檛 hesitate to comment or get in touch with me (matt at ooiio dot com). Also expect to see updates to this tutorial as APIs change and I get a little more time to clean up my code. Feel free to download and play with my little todo app: todo-tutorial.tar.gz or todo-tutorial.zip. Consider them released under a BSD-style license. Above all, don鈥檛 sue me. django-admin.py is Django's command-line utility for administrative tasks. This document outlines all it can do. django-admin.py鏄疍jango鐨勫懡浠よ綆$悊緋葷粺錛岃繖綃囨枃妗e皢璇︾粏浠嬬粛浠栫殑鍔熻兘銆?/p>
In addition, manage.py is automatically created in each Django project. manage.py is a thin wrapper around django-admin.py that takes care of two things for you before delegating to django-admin.py: The django-admin.py script should be on your system path if you installed Django via its setup.py utility. If it's not on your path, you can find it in site-packages/django/bin within your Python installation. Consider symlinking to it from some place on your path, such as /usr/local/bin. Generally, when working on a single Django project, it's easier to use manage.py. Use django-admin.py with DJANGO_SETTINGS_MODULE, or the --settings command line option, if you need to switch between multiple Django settings files. django-admin.py action [options] manage.py action [options] action should be one of the actions listed in this document. options, which is optional, should be zero or more of the options listed in this document. Run django-admin.py --help to display a help message that includes a terse list of all available actions and options. Most actions take a list of appname``s. An ``appname is the basename of the package containing your models. For example, if your INSTALLED_APPS contains the string 'mysite.blog', the appname is blog. Prints the admin-index template snippet for the given appnames. Use admin-index template snippets if you want to customize the look and feel of your admin's index page. See Tutorial 2 for more information. Creates a cache table named tablename for use with the database cache backend. See the cache documentation for more information. Runs the command-line client for the database engine specified in your DATABASE_ENGINE setting, with the connection parameters specified in your DATABASE_USER, DATABASE_PASSWORD, etc., settings. This command assumes the programs are on your PATH so that a simple call to the program name (psql, mysql, sqlite3) will find the program in the right place. There's no way to specify the location of the program manually. Displays differences between the current settings file and Django's default settings. Settings that don't appear in the defaults are followed by "###". For example, the default settings don't define ROOT_URLCONF, so ROOT_URLCONF is followed by "###" in the output of diffsettings. Note that Django's default settings live in django/conf/global_settings.py, if you're ever curious to see the full list of defaults. Introspects the database tables in the database pointed-to by the DATABASE_NAME setting and outputs a Django model module (a models.py file) to standard output. Use this if you have a legacy database with which you'd like to use Django. The script will inspect the database and create a model for each table within it. As you might expect, the created models will have an attribute for every field in the table. Note that inspectdb has a few special cases in its field-name output: This feature is meant as a shortcut, not as definitive model generation. After you run it, you'll want to look over the generated models yourself to make customizations. In particular, you'll need to rearrange models' order, so that models that refer to other models are ordered properly. Primary keys are automatically introspected for PostgreSQL, MySQL and SQLite, in which case Django puts in the primary_key=True where needed. inspectdb works with PostgreSQL, MySQL and SQLite. Foreign-key detection only works in PostgreSQL and with certain types of MySQL tables. Executes the equivalent of sqlall for the given appnames. Starts a lightweight development Web server on the local machine. By default, the server runs on port 8000 on the IP address 127.0.0.1. You can pass in an IP address and port number explicitly. If you run this script as a user with normal privileges (recommended), you might not have access to start a port on a low port number. Low port numbers are reserved for the superuser (root). DO NOT USE THIS SERVER IN A PRODUCTION SETTING. It has not gone through security audits or performance tests. (And that's how it's gonna stay. We're in the business of making Web frameworks, not Web servers, so improving this server to be able to handle a production environment is outside the scope of Django.) The development server automatically reloads Python code for each request, as needed. You don't need to restart the server for code changes to take effect. When you start the server, and each time you change Python code while the server is running, the server will validate all of your installed models. (See the validate command below.) If the validator finds errors, it will print them to standard output, but it won't stop the server. You can run as many servers as you want, as long as they're on separate ports. Just execute django-admin.py runserver more than once. Note that the default IP address, 127.0.0.1, is not accessible from other machines on your network. To make your development server viewable to other machines on the network, use its own IP address (e.g. 192.168.2.1) or 0.0.0.0. Port 7000 on IP address 127.0.0.1: Port 7000 on IP address 1.2.3.4: By default, the development server doesn't serve any static files for your site (such as CSS files, images, things under MEDIA_ROOT_URL and so forth). If you want to configure Django to serve static media, read the serving static files documentation. To disable auto-reloading of code while the development server is running, use the --noreload option, like so: Starts the Python interactive interpreter. Django will use IPython, if it's installed. If you have IPython installed and want to force use of the "plain" Python interpreter, use the --plain option, like so: django-admin.py shell --plain sql [appname appname ...] Prints the CREATE TABLE SQL statements for the given appnames. Prints the CREATE TABLE and initial-data SQL statements for the given appnames. Refer to the description of sqlinitialdata for an explanation of how to specify initial data. Prints the DROP TABLE SQL statements for the given appnames. Prints the CREATE INDEX SQL statements for the given appnames. Prints the initial INSERT SQL statements for the given appnames. For each model in each specified app, this command looks for the file <appname>/sql/<modelname>.sql, where <appname> is the given appname and <modelname> is the model's name in lowercase. For example, if you have an app news that includes a Story model, sqlinitialdata will attempt to read a file news/sql/story.sql and append it to the output of this command. Each of the SQL files, if given, is expected to contain valid SQL. The SQL files are piped directly into the database after all of the models' table-creation statements have been executed. Use this SQL hook to populate tables with any necessary initial records, SQL functions or test data. Prints the DROP TABLE SQL, then the CREATE TABLE SQL, for the given appnames. Prints the SQL statements for resetting PostgreSQL sequences for the given appnames. See http://simon.incutio.com/archive/2004/04/21/postgres for more information. Creates a Django app directory structure for the given app name in the current directory. Creates a Django project directory structure for the given project name in the current directory. Creates the database tables for all apps in INSTALLED_APPS whose tables have not already been created. Use this command when you've added new applications to your project and want to install them in the database. This includes any apps shipped with Django that might be in INSTALLED_APPS by default. When you start a new project, run this command to install the default apps. If you're installing the django.contrib.auth application, syncdb will give you the option of creating a superuser immediately. New in Django development version Discover and run tests for all installed models. See Testing Django applications for more information. Validates all installed models (according to the INSTALLED_APPS setting) and prints validation errors to standard output. Example usage: Explicitly specifies the settings module to use. The settings module should be in Python package syntax, e.g. mysite.settings. If this isn't provided, django-admin.py will use the DJANGO_SETTINGS_MODULE environment variable. Note that this option is unnecessary in manage.py, because it takes care of setting DJANGO_SETTINGS_MODULE for you. Example usage: Adds the given filesystem path to the Python import search path. If this isn't provided, django-admin.py will use the PYTHONPATH environment variable. Note that this option is unnecessary in manage.py, because it takes care of setting the Python path for you. Displays a help message that includes a terse list of all available actions and options. New in Django development version Inform django-admin that the user should NOT be prompted for any input. Useful if the django-admin script will be executed as an unattended, automated script. Disable the use of the auto-reloader when running the development server. Displays the current Django version. Example output: New in Django development version Example usage: Verbosity determines the amount of notification and debug information that will be printed to the console. '0' is no output, '1' is normal output, and 2 is verbose output. New in Django development version Tells Django where to find the various CSS and JavaScript files for the admin interface when running the development server. Normally these files are served out of the Django source tree, but because some designers customize these files for their site, this option allows you to test against custom versions. The django-admin.py / manage.py commands that output SQL to standard output will use pretty color-coded output if your terminal supports ANSI-colored output. It won't use the color codes if you're piping the command's output to another program. If you use the Bash shell, consider installing the Django bash completion script, which lives in extras/django_bash_completion in the Django distribution. It enables tab-completion of django-admin.py and manage.py commands, so you can, for instance... A small addition: Powered by Zoundry
]]>
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice = models.CharField(max_length=200)
votes = models.IntegerField()
瀹夎Django
寤鴻瀹夎python2.5鍙婁互涓婄増鏈紝浣嗕笉寤鴻浣跨敤python3.0銆?/h2>
鏁版嵁搴撳鏋滀嬌鐢╯qllite錛宲ython宸茬粡鍐呭緩錛屼笉闇鍙﹁瀹夎錛屽鏋滈渶瑕佷嬌鐢╩yslq鎴栧叾浠栨暟鎹簱錛岄渶瑕佽嚜琛屽畨瑁呫?br />
鎺ヤ笅鏉ュ畨瑁匘jango錛堝湪widnwos涓嬶級錛?br />
1銆佷粠http://www.djangoproject.com/download/涓嬭澆Django
2銆佸湪windwos涓嬩嬌鐢╬ython setup.py install 瀹夎錛堟垜鍘熸兂浣跨敤python setup.py develop瀹夎錛屾病鎴愬姛錛夛紝鍓嶆彁鏄緗ソpython鐜鍜屽凡瀹夎setuptools銆?br />
3銆佸皢python瀹夎鐩綍涓媗ib\site-packages\django\bin\django-admin.py 澶嶅埗鍒皃ython瀹夎鐩綍涓嬬殑\scripts\鐩綍銆?br />
涓嬮潰鍙互嫻嬭瘯涓涓嬶紝鍚姩cmd紿楀彛錛?br />
C:\Documents and Settings\Administrator>python
>>> import django
>>> django.VERSION
(1, 2, 0, 'rc', 1)
瀹夎OK銆傚紑濮嬪垱寤虹涓涓猵roject鍚с?br />
1銆侀夊畾涓涓洰褰曪紝鍚姩cmd紿楀彛錛?br />
F:\temp>django-admin.py startproject mysite2
F:\temp>
榪欏皢鍦ㄥ綋鍓嶇洰褰曚笅鏂板緩涓涓猵roject錛屽悕瀛椾負mysite2錛堟敞鎰忎笉瑕佷嬌鐢?django"絳変繚鐣欏瓧浣滀負project鍚嶇О錛夛紝鐩綍緇撴瀯涓猴細
2010-05-30 13:29 <DIR> .
2010-05-30 13:29 <DIR> ..
2010-05-30 13:29 557 manage.py
2010-05-30 13:29 3,387 settings.py
2010-05-30 13:29 561 urls.py
2010-05-30 13:29 0 __init__.py
4 涓枃浠?nbsp; 4,505 瀛楄妭
2 涓洰褰?29,717,716,992 鍙敤瀛楄妭
鍏堜簡瑙h繖涔堝鍚э紝璇︾粏鐨勬枃浠跺唴瀹瑰崟鐙啀璇淬?br />
2銆佸惎鍔╤ttp server:
F:\temp\mysite2>python manage.py runserver
Validating models...
0 errors found
Django version 1.2 rc 1, using settings 'mysite2.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
鎵撳紑web browser錛岃緭鍏ュ湴鍧http://127.0.0.1:8000/錛屽彲浠ョ湅鍒皊erver宸茬粡鍚姩浜嗐傚綋鐒訛紝濡傛灉浣犲笇鏈涙崲涓涓鍙o紝鍙互浣跨敤錛?span style="font-family: monospace;">
python manage.py runserver 绔彛鍙?br />
3銆佹帴鐫閰嶇疆database錛?br />
'django.contrib.contenttypes',鍐呭綆$悊?
'django.contrib.sessions',session鎺у埗
'django.contrib.sites',澶歴ite綆$悊
濡傛灉鐢ㄤ笉鍒拌app錛屽彲浠ユ敞閲婃帀錛岃繖灝嗕笉鍦╠atabase涓緩绔嬬浉鍏崇鐞唗ables銆傜劧鍚庝嬌鐢細
python manage.py syncdb
寤虹珛鐩稿簲鐨則ables銆?br />
4銆佸湪mysite2鐩綍涓嬶紝鏂板緩涓涓嚜宸辯殑app錛?br />
python manage.py startapp polls
灝嗘柊寤轟竴涓猵olls鐩綍錛屽唴瀹瑰涓嬶細
2010-05-30 14:07 <DIR> .
2010-05-30 14:07 <DIR> ..
2010-05-30 14:07 60 models.py
2010-05-30 14:07 537 tests.py
2010-05-30 14:07 27 views.py
2010-05-30 14:07 0 __init__.py
5銆佸垱寤簃odels錛?br />
緙栬緫models.py,鍐呭濡備笅錛?br />
from django.db import models
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice = models.CharField(max_length=200)
votes = models.IntegerField()
榪欓噷鏈変袱涓猰odel錛孭oll鍜孋hoice錛岃繕瀛樺湪涓涓猳ne Poll to many Choice鍏崇郴銆?br />
鍦╯etting.py 涓皢polls 鍔犲叆鍒癷nstalled app 鑺傜偣涓紝鐒跺悗浣跨敤python manage.py syncdb 灝嗗湪database涓柊寤虹浉搴旂殑tables銆?span style="font-family: sans-serif;">table name 鍒嗗埆鏄細
polls_poll,polls_choice銆?br />
褰撶劧榪樻湁鍏朵粬涓浜沵anage command:
6銆佷嬌鐢╠jango shell錛?br />
python manage.py shell
榪欎釜cmd鑳屽悗鍋氫簡涓や歡浜嬶細涓鏄皢mysite2鍔犲叆鍒皊ys.path涓幓錛涗簩鏄柊寤轟簡DJANGO_SETTINGS_MODULE鐜鍙橀噺錛屽彲浠ュ紩鐢╯ettings.py涓殑閰嶇疆鍐呭銆?br />
鎺ヤ笅鏉ュ氨鍙互嫻嬭瘯浜嗐?br />
]]>
BTW錛氬鏋滄湁濂界殑鍦ㄧ嚎緲昏瘧騫沖彴錛屽摢浣嶇煡鎴戜竴澹般?br />
]]>
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
]]>
2銆佸湪url.py patterns涓鍔犱竴琛岋細
(r'^site_media/(?P<path>.*)$','django.views.static.serve',{'document_root':settings.STATIC_PATH}),
榪樿from django.conf import setting
3銆佸湪setting.py涓姞鍏ヤ竴琛岋細
STATIC_PATH='./medias'
濡傛璁劇疆鍚庯紝灝卞彲浠ュ湪template file 涓紩鐢╩edia涓瓨鏀劇殑闈欐佹枃浠朵簡錛屽錛?br />
<img src='/site_media/django.gif'>
璇︾粏鍙limodou鍐欑殑django step by step
]]>
1=django_py.acp
2=epydoc.acp
錛堣禐錛侊級
3銆佸湪acp鏂囦歡涓殑瀹氫箟鐨勫錛?br />
(^\s*)cdef<space> = "\\1def ${1:}(self, ${2:}):\n\t${0}"
鍦ㄥ嚑涓?{*:}涔嬮棿鍙互鐢╰ab閿洿鎺ヨ漿縐昏緭鍏ヤ綅緗?br />
4銆佸湪acp鏂囦歡涓嬌鐢?#8220;[”鐨勮嚜鍔ㄥ畬鎴愶細
[autostring_append]
[="!^]"
鎴戞兂鍦ㄨ緭鍏鍚庤嚜鍔ㄨˉ涓篬]錛岀敱浜嶽琚畾涔変負浜哸cp鏂囦歡涓殑涓涓猭ey錛屽洜姝ゅ簲璇ヨ繖鏍峰畾涔夛細
[autostring_append]
<square>="!^]"
榪欎釜questtion榪樺緱鍒頒簡limodou鐨勫洖絳?/a>錛岄潪甯告劅璋紒
鏇村鍔熻兘涓?a >ulipad鐨刧oogle緇?/a>
]]>address = [
('寮犱笁', '鍦板潃涓'),
('鏉庡洓', '鍦板潃浜?)
]
閭d箞鍙互鍦╰emplate鏂囦歡csv.html涓嬌鐢?br />row.0....鏂瑰紡寮曠敤銆?br />鐢變簬姝ゅ墠鎴戜粠涓婁竴璁插鍒朵簡address鐨勫畾涔夛細
address=[
{'name':'寮犱笁','address':'媧涢槼鏍懼窛'},
{'name':'閲屾柉','address':'鏁存暣緇滄暎緇?}
]
鎵浠ヤ嬌鐢╮ow.0鏂瑰紡寮曠敤鏃訛紝django涓嶄細鎶ラ敊錛屼絾灝辨槸浠涔堝唴瀹逛篃娌℃湁錛屼嬌鐢╮ow.name鏂瑰紡搴旂敤鍚庢甯搞?br />
]]>
]]>
Django Generic Views: CRUD
Published by Matt Croydon August 17th, 2005 in Projects, Python, Django
Note:Getting Started
django-admin.py startproject todo
. Make sure that the directory you created your project in is in your PYTHONPATH
, then edit todo/settings/main.py
to point to the database of your choice. Now would be a good time to set your DJANGO_SETTINGS_MODULE
to "todo.settings.main"
. Next move to your apps/
dir and create a new application: django-admin.py startapp tasks
and django-admin.py init
. The initial setup process is covered in much more detail in tutorial 1.The Model
todo/apps/tasks/models/tasks.py
):
from django.core import meta
# Create your models here.
class Task(meta.Model):
fields = (
meta.CharField('title', maxlength=200),
meta.TextField('description'),
meta.DateTimeField('create_date', 'date created'),
meta.DateTimeField('due_date', 'date due'),
meta.BooleanField('done'),
)
admin = meta.Admin(
list_display = ( 'title', 'description', 'create_date', 'due_date', 'done' ),
search_fields = ['title', 'description'],
date_hierarchy = 'due_date',
)
def __repr__(self):
return self.title
INSTALLD_APPS
in todo/settings/main.py
: 'todo.apps.tasks',
URL Configuration
todo/settings/urls/main.py
directly, but you鈥檙e probably best off decoupling your URLs to your specific app as mentiond in tutorial 3.
from django.conf.urls.defaults import *
info_dict = {
'app_label': 'tasks',
'module_name': 'tasks',
}
urlpatterns = patterns('',
(r'^tasks/?$', 'todo.apps.tasks.views.tasks.index'),
(r'^tasks/create/?$', 'django.views.generic.create_update.create_object',
dict(info_dict, post_save_redirect="/tasks/") ),
(r'^tasks/update/(?P<object_id>d+)/?$',
'django.views.generic.create_update.update_object', info_dict),
(r'^tasks/delete/(?P<object_id>d+)/?$',
'django.views.generic.create_update.delete_object',
dict(info_dict, post_delete_redirect="/tasks/new/") ),
(r'^tasks/complete/(?P<object_id>d+)/?$',
'todo.apps.tasks.views.tasks.complete'),
)
info_dict
to pass information about our application and module to the generic view handlers . The CRUD generic views need only provide these two pieces of information, but some generic views need more. See the generic views documentation for an explanation.Index
(r'^tasks/?$', 'todo.apps.tasks.views.tasks.index'),
todo/apps/tasks/views/tasks.py
:
from django.core import template_loader
from django.core.extensions import DjangoContext as Context
from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect
from django.models.tasks import tasks
from django.core.exceptions import Http404
def index(request):
notdone_task_list = tasks.get_list(order_by=['-due_date'], done__exact=False)
done_task_list = tasks.get_list(order_by=['-due_date'], done__exact=True)
t = template_loader.get_template('tasks/index')
c = Context(request, {
'notdone_tasks_list': notdone_task_list,
'done_tasks_list': notdone_task_list,
})
return HttpResponse(t.render(c))
notdone_tasks_list
is (not suprisingly) a list of tasks that are not done yet. Similarly, done_tasks_list
contains a list of tasks that have been completed. We will use the template tasks/index.html
to render this view.todo/settings/main.py
). Here鈥檚 mine:
TEMPLATE_DIRS = (
"/home/mcroydon/django/todo/templates",
)
{% if notdone_tasks_list %}
<p>Pending Tasks:</p>
<ul>
{% for task in notdone_tasks_list %}
<li>{{ task.title }}: {{ task.description }} <br/>
Due {{ task.due_date }} <br/>
<a href="/tasks/update/{{ task.id }}/">Update</a>
<a href="/tasks/complete/{{ task.id }}/">Complete</a>
</li>
{% endfor %}
</ul>
{% else %}
<p>No tasks pending.</p>
{% endif %}
<p>Completed Tasks:</p>
<ul>
{% if done_tasks_list %}
{% for task in done_tasks_list %}
<li>{{ task.title }}: {{ task.description }} <br/>
<a href="/tasks/delete/{{ task.id }}/">Delete</a>
</li>
{% endfor %}
</ul>
{% else %}
<p>No completed pending.</p>
{% endif %}
<p><a href="/tasks/create/">Add a task</a></p>
Create Generic View
(r'^tasks/create/?$', 'django.views.generic.create_update.create_object', dict(info_dict, post_save_redirect="/tasks/") ),
create_object
generic view every time we visit /tasks/create/
. If we arrive there with a GET
request, the generic view displays a form. Specifically it鈥檚 looking for module_name_form.html
. In our case it will be looking for tasks_form
. It knows what model to look for because of the information we gave it in info_dict
. If however we reach this URL via a POST
, the create_object
generic view will create a new object for us and then redirect us to the URL of our choice (as long as we give it a post_save_redirect
).tasks_form.html
:
{% block content %}
{% if object %}
<h1>Update task:</h1>
{% else %}
<h1>Create a Task</h1>
{% endif %}
{% if form.has_errors %}
<h2>Please correct the following error{{ form.errors|pluralize }}:</h2>
{% endif %}
<form method="post" action=".">
<p><label for="id_title">Title:</label> {{ form.title }}
{% if form.title.errors %}*** {{ form.title.errors|join:", " }}{% endif %}</p>
<p><label for="id_description">Description:</label> {{ form.description }}
{% if form.description.errors %}*** {{ form.description.errors|join:", " }}{% endif %}</p>
<p><label for="id_create_date_date">Create Date:</label> {{ form.create_date_date }}
{% if form.create_date_date.errors %}*** {{ form.create_date_date.errors|join:", " }}{% endif %}</p>
<p><label for="id_create_date_time">Create Time:</label> {{ form.create_date_time }}
{% if form.create_date_time.errors %}*** {{ form.create_date_time.errors|join:", " }}{% endif %}</p>
<p><label for="id_due_date_date">Due Date:</label> {{ form.due_date_date }}
{% if form.due_date_date.errors %}*** {{ form.due_date_date.errors|join:", " }}{% endif %}</p>
<p><label for="id_due_date_time">Due Time:</label> {{ form.due_date_time }}
{% if form.due_date_time.errors %}*** {{ form.due_date_time.errors|join:", " }}{% endif %}</p>
<p><label for="id_done">Done:</label> {{ form.done }}
{% if form.done.errors %}*** {{ form.done.errors|join:", " }}{% endif %}</p>
<input type="submit" />
</form>
<!--
This is a lifesaver when debugging!
<p> {{ form.error_dict }} </p>
-->
{% endblock %}
Update
(r'^tasks/update/(?P<object_id>\d+)/?$', 'django.views.generic.create_update.update_object', info_dict),
tasks_form.html
, so with a little logic, 90% of the form can be exactly the same as the create form. If we go to /tasks/create/
, we get the blank form. If we visit /tasks/update/1/
we will go to the same form but it will be prepopulated with the data from the task with the ID of 1. Here鈥檚 the logic that I used to change the header:
{% if object %}
<h1>Update task:</h1>
{% else %}
<h1>Create a Task</h1>
{% endif %}
Delete
(r'^tasks/delete/(?P<object_id>\d+)/?$', 'django.views.generic.create_update.delete_object', dict(info_dict, post_delete_redirect="/tasks/new/") ),
/tasks/delete/1
using a GET
request, Django will automatically send us to the tasks_form_delete.html
template. This allows us to make sure that the user really wanted to delete the task. here鈥檚 my very simple tasks_form_delete.html
template:
<form method="post" action=".">
<p>Are you sure?</p>
<input type="submit" />
</form>
post_delete_redirect
.CRUD Generic Views And the Rest of Your Application
(r'^tasks/complete/(?P<object_id>\d+)/?$', 'todo.apps.tasks.views.tasks.complete'),
todo/apps/tasks/models/tasks.py
):
def complete(request, object_id):
try:
t = tasks.get_object(pk=object_id)
except:
# do something better than this
raise Http404
try:
t.done=True
t.save()
return HttpResponseRedirect('/tasks/')
except:
# do something better than this
raise Http404
Conclusion
24 Responses to 鈥淒jango Generic Views: CRUD鈥?/h4>
]]>
]]>
]]>django-admin.py and manage.py
This covers Django version 0.95 and the development version. Old docs: 0.90, 0.91
瀹為檯涓婏紝鏂囦歡manage.py浼氬湪姣忎釜Django宸ョ▼鍒涚珛鐨勬椂鍊欒嚜鍔ㄥ緩绔嬶紝manage.py鏄痙jango-admin.py鍔熻兘鐨勪竴涓畝鍗曞皝瑁咃紝瀹冧細涓篸jango-admin.py鍚敤涔嬪墠鍋氬ソ涓ら」宸ヤ綔錛?/p>
濡傛灉浣犻氳繃setup.py鏂瑰紡瀹夎Django錛宒jango-admin.py鑴氭湰浼氳鍔犲叆鍒扮郴緇熻礬寰勩傚鏋滀笉鍦ㄧ郴緇熻礬寰勶紝浣犲彲浠ュ湪Python瀹夎璺緞涓嬬殑site-packages/django/bin鐩綍涓嬫壘鍒幫紝騫跺皢浠栧姞鍏ュ埌浣犵殑緋葷粺璺緞涓嬨?/p>
涓鑸儏鍐典笅錛屽鍗曚釜Django project錛屼嬌鐢╩anage.py娌℃湁浠涔堥棶棰橈紝濡傛灉浣犻渶瑕佸湪涓嶅悓鐨凞jango project闂翠嬌鐢╠jango-admin.py錛岄偅涔堥渶瑕佷嬌鐢―JANGO_SETTINGS_MODULE鎴?-settings鍛戒護琛屽弬鏁般?/p>
Usage
Available actions
adminindex [appname appname ...]
createcachetable [tablename]
dbshell
diffsettings
姣旇緝褰撳墠settings鏂囦歡鍜孌jango緙虹渷settings鏂囦歡涔嬮棿鐨勫樊寮傘?/p>
鍦ㄧ己鐪乻ettings涓笉瀛樺湪鐨勪互"###"鏍囪瘑銆?/p>
inspectdb
install [appname appname ...]
runserver [optional port number, or ipaddr:port]
Examples:
django-admin.py runserver 7000
django-admin.py runserver 1.2.3.4:7000
Serving static files with the development server
Turning off auto-reload
濡傛灉瑕佸湪鏈嶅姟宸插惎鍔ㄥ悗紱佹鑷姩鍔犺澆浠g爜鍔熻兘錛屽彲浣跨敤--noreload鍙傛暟銆?/p>
django-admin.py runserver --noreload
shell
sqlall [appname appname ...]
sqlclear [appname appname ...]
sqlindexes [appname appname ...]
sqlinitialdata [appname appname ...]
sqlreset [appname appname ...]
sqlsequencereset [appname appname ...]
startapp [appname]
startproject [projectname]
syncdb
test
validate
Available options
--settings
django-admin.py syncdb --settings=mysite.settings
--pythonpath
django-admin.py syncdb --pythonpath='/home/djangoprojects/myproject'
--help
--noinput
--noreload
--version
0.9.1
0.9.1 (SVN)
--verbosity
django-admin.py syncdb --verbosity=2
verbosity鍐沖畾榪愯銆佽皟璇曚俊鎭樉紺虹駭鍒紝0錛嶄粈涔堜篃涓嶈緭鍑猴紝1錛嶆甯歌緭鍑猴紝2錛嶈緇嗕俊鎭緭鍑?/p>
--adminmedia
Extra niceties
Syntax coloring
Bash completion
Comments
Indy September 27, 2006 at 4:04 a.m.
"Note that the default IP address, 127.0.0.1, is not accessible from other machines on your network. To make your development server viewable to other machines on the network, use its own IP address (e.g. 192.168.2.1) or 0.0.0.0." ... _as start parameter (e.g. manage.py runserver 192.168.2.1:8000)_
]]>
]]>
]]>
闅鵑亾蹇呴』浣跨敤鑷畾涔夌殑妯℃澘璇█錛?br />
]]>
妯℃澘
1銆佺敤 html 鏂囦歡淇濆瓨錛岃璁$殑鍙橀噺鐢?{{value_name}} 濉厖
2銆侀渶 from django.template import Template,Context 瀵煎叆搴?
3銆乼=Template( 妯℃澘鏂囦歡鍚?)聽
聽c=Context( 妯℃澘鍙橀噺鍐呭 )
聽t.render(c)# 鍙互杈撳嚭妯℃澘鍐呭
4銆伮犅?涓嬮潰榪欐涓嶇悊瑙d粈涔堟剰鎬?
聽To prevent this, set a function attribute alters_data on the method. The template system won 鈥?t execute a method if the method has alters_data=True set. For example:
聽def delete(self):
聽聽# Delete the account
聽delete.alters_data = True
5銆?Context 瀵硅薄鏀寔 push()/pop() 鏂規硶
6銆?妯℃澘鏂囦歡涓殑鏍囩錛?
聽娌℃湁 elseif;
聽For 寰幆涓病鏈?break 鍜?continue
聽For 寰幆涓殑鍑犱釜灞炴э細
聽聽聽 forloop.counter聽聽聽聽 # 褰撳墠寰幆鐨勬鏁幫紝浠?1 寮濮?
聽聽聽 forloop.counter0聽聽聽 # 褰撳墠寰幆鐨勬鏁幫紝浠?0 寮濮?
聽聽聽 forloop.revcounter聽聽聽聽聽聽聽 # 褰撳墠寰幆鍓╀綑嬈℃暟錛屼粠鎬誨驚鐜鏁伴掑噺
聽聽聽 forloop.revcounter0聽聽聽聽聽聽 # 褰撳墠寰幆鍓╀綑嬈℃暟錛屼粠鎬誨驚鐜鏁?-1 閫掑噺
聽聽聽 forloop.first聽聽聽聽聽聽聽聽聽聽聽聽 #boolean 鍊鹼紝濡傛灉涓虹涓嬈″驚鐜紝鍊間負鐪?
聽聽聽 forloop.last聽聽聽聽聽聽聽聽聽聽聽聽聽 # 鍚屼笂
聽聽聽 forloop.parentloop聽聽聽聽聽聽聽 # 寮曠敤鐖跺驚鐜殑 forloop 瀵硅薄
聽ifequal A B聽 錛?AB 鍙兘鏄ā鏉垮彉閲忋佸瓧絎︿覆銆佹暟瀛?
聽聽聽 pass 錛冨鏋?A B 鐩哥瓑鍒欐墽琛?
聽else
聽聽聽 pass 錛冨惁鍒欐墽琛?
聽endifequal
聽{#聽聽 #}聽聽聽聽聽 錛冩敞閲?
聽{{A|B:鈥漵鈥潁}聽聽聽聽聽聽聽聽 # 瀵?A 鎵ц B 榪囨護錛?B 榪囨護鍙互鏈夊弬鏁?
聽聽 鍑犱釜榪囨護鍣細
聽聽 addslashes聽聽聽 鍔犲弽鏂滄潬
聽聽 Date聽聽聽聽聽聽聽聽聽 鏍煎紡鍖栨棩鏈熶負瀛楃涓?
聽聽 escape聽聽聽聽聽聽聽 杞崲涓虹綉欏電紪鐮?
聽聽 length聽聽聽聽聽聽聽 闀垮害
7銆?妯℃澘涓嶈兘寤虹珛涓涓彉閲忔垨鑰呮敼鍙樹竴涓彉閲忕殑鍊鹼紱涓嶈兘璋冪敤鍘熺敓鐨?python 浠g爜
8銆?鍦?setting.py 涓埗瀹氭ā鏉挎枃浠跺瓨鏀劇殑鐩綍錛?EMPLATE_DIRS 錛夛紝渚嬶細
聽TEMPLATE_DIRS = (
聽聽'/home/django/mysite/templates',
聽)
聽涓嶈蹇樹簡鏈鍚庣殑閫楀彿錛岄櫎闈炰綘灝嗗簭鍒楋紙錛夋崲鎴愬垪琛?[] 錛屼絾鏁堢巼浼氶檷浣庯紱鐩綍鐢?/ 闂撮殧
9銆?浣跨敤妯℃澘錛?
聽from django.shortcuts import render_to_response
聽import datetime
聽def current_datetime(request):
聽聽now = datetime.datetime.now()
聽return render_to_response('current_datetime.html', {'current_date': now})
聽鍙互灝嗗~鍏呭埌妯℃澘鐨勫彉閲忔崲涓簂ocals()錛屼絾鎬ц兘浼氭湁鎵涓嬮檷錛屽
聽def current_datetime(request):
聽聽current_date = datetime.datetime.now()
聽聽聽聽return render_to_response('current_datetime.html', locals())
10銆佸鏋滆寮曠敤璁懼畾鐨勬ā鏉跨洰褰曚腑瀛愮洰褰曠殑妯℃澘鏂囦歡 ;
聽t = get_template('dateapp/current_datetime.html')
11銆佹ā鏉垮彲宓屽錛屾ā鏉挎枃浠跺悕鍙敤鍙橀噺
聽{% include 'includes/nav.html' %}
聽{% include template_name %}
12銆佹ā鏉跨戶鎵匡紝浣跨敤 extends 鍜屼竴涓壒孌婄殑鏍囩 block 錛屼緥錛?
聽錛僢ase.html
聽<head>
聽<title>
聽聽{% block title %}鏍囬{% endblock %}
聽</title>
聽</head>
聽<body>
聽{% block content %}鍐呭{% endblock %}
聽{% block footer %} 欏靛熬{% endblock %}
聽</body>
聽</html>
聽 涓嬮潰鐨勬ā鏉跨戶鎵胯嚜 base.html
聽{% extends "base.html" %}聽聽聽聽 錛冭繖涓琛屽繀欏繪槸絎竴涓ā鏉挎爣絳捐
聽{% block title %} 鎴戠殑鏍囬 {% endblock %}
聽{% block content %}
聽聽<p> 鎴戠殑鍐呭 </p>
聽{% endblock %}聽聽 錛冧笉涓瀹氳閲嶆柊瀹氫箟鐖舵ā鏉夸腑鐨勬瘡涓ā鏉垮潡
聽閫氳繃 block.super 寮曠敤鐖舵ā鏉垮潡鍐呭
http://groups.google.com/group/django-users django鐨刧oogle璁哄潧鍒楄〃
http://www.djangoproject.com/documentation/ django瀹樻柟鏂囨。
http://code.djangoproject.com/browser/django/trunk/docs django瀹樻柟鏈鏂版枃妗?鍙笅杞?/p>
浠ュ墠鐪嬭繃錛岄噸鏂版俯涔狅紝寮濮嬬湅python妗嗘灦Django錛屽凡緇忓畨瑁咃紝榛樿鍒濆嬈㈣繋鐣岄潰宸茬粡鍑虹幇浜嗭紝鏍規嵁http://www.woodpecker.org.cn/obp/django/django-stepbystep/newtest/doc/#id3浠嬬粛鍐呭瀛︿範錛屽嵈鍑虹幇浜嗛敊璇細
Could not import newtest.helloworld. Error was: No module named httpwrappers
鏌ョ湅django lib錛岀‘瀹炴病鏈夎繖涓被錛屾煡鎵懼師鍥爄ng鈥?.....
[24鏃ヨˉ鍏匽
google鍒頒簡鍘熷洜錛?br />HttpResponse綾諱粠django.utils.httpwrapers鏀瑰埌浜哾jango.http
鍙傝錛?br />http://python.cn/pipermail/python-chinese/2006-April/023980.html
http://code.djangoproject.com/wiki/NamespaceSimplification
[鍐嶈ˉ鍏匽
鑷垜鎰熻dj鐨勭己鐐癸細鍗曠嫭鐨勬爣絳懼簱錛屾病鏈夊畬鍏ㄤ嬌鐢╬ython錛涙鏋剁粨鏋勪笉鏄緢娓呮櫚錛屼笉濡倀apestry錛?br />
What would you think about making a screencast, a la Rails? That was a lot of Python to read, and I ended up skipping over it pretty quickly.
Cool stuff, but I noticed that the pluralize filter doesn鈥檛 work (see screenshot)
Dagur,
Yeah I noticed that but forgot to investigate it. I鈥檒l let you know what I find out.
Steve,
Yeah, that would rock. I didn鈥檛 realize how much code I was going to have to escape and format before this post was done!
This is some cool stuff! It would be nice to have it as part of official Django documentation, if some small typos are corrected.
Unfortunately this example doesn鈥檛 work out of box.
1) Getting Started 鈥?make sure to create your database _before_ you run django-admin.py init. It is not going to be created for you. Official Tutorial 1 (which is mentioned after 鈥渋nit鈥? explains it in details.
2) The Model 鈥?before going to play with the model make sure to install it using django-admin.py install tasks. It is explained in Official Tutorial 1.
3) URL Configuration 鈥?probably urls should be decoupled as in Official Tutorial 3. It is better for novices to provide ready-made code instead of reference to Official Tutorial 3.
4) URL Configuration 鈥?update should have the same parameters as create. Otherwise it doesn鈥檛 know where to forward to after updating.
5) URL Configuration 鈥?most probably delete should forward to 鈥?tasks/鈥? 鈥?tasks/new/鈥?is not defined in your tutorial.
6) Index 鈥?the same list is passed as 鈥榥otdone_tasks_list鈥?and 鈥榙one_tasks_list鈥? The latter should be done_task_list.
7) Index 鈥?it should be noted that all template files are to be created in subdirectory 鈥榯emplates/tasks/鈥? not directly in 鈥榯emplates/鈥?
8) Create Generic View 鈥?by some reasons tasks_form template has all 鈥樷濃?prepended with 鈥榎\鈥? They should be removed, otherwise it doesn鈥檛 work.
9) Delete 鈥?tasks_form_delete template should be renamed to tasks_confirm_delete.
I鈥檓 pretty sure that these tiny bugs are due to ongoing changes in Django and naturally occurring typos. Thank you for great tutorial!
Eugene,
Hey thanks for the feedback, I鈥檒l do my best to update the tutorial this weekend. I did my best to get from scratch to my working situation, but I sure missed a couple of things along the way.
Thanks again for taking the time to go throught the tutorial and pointing out the little things.
Be aware that there are some significant and backwards-incompatible syntax changes for the models that might be showing up shortly, but I鈥檒l definitely update this tutorial when/if that happens.
Great article.
Few minor additions that will help others (newb->newb). (I鈥檓 running django revision 525, FYI.)
1. A little reminder to 鈥渄jango-admin.py init tasks鈥?to create the database table in the initialized database would help just before the screen pic of the index.html.
2. (r鈥橿tasks/delete/(?P\d+)/?$鈥? [鈥 post_delete_redirect=鈥?tasks/new/鈥? ),
seems to work as
(r鈥橿tasks/delete/(?P\d+)/?$鈥? [鈥 post_delete_redirect=鈥?tasks/create/鈥? ),
instead.
3. tasks_form_delete.html template seems to work as tasks_confirm_delete.hmtl instead
-=-
Awesome bite-sized article. Thanks for sharing.
I forgot to mention django-admin.py createsuperuser.
Matt, thank you the tutorial. I tried it but stopped with
/tasks/create/
because in my MS Explorer there is no submit button shown. Only input field.
Is it a problem on my side( django installation or MS Explorer or similar)?
Thank you for your reply
@Lada
You need to edit the template 鈥渢asks_form.html鈥?and change all \鈥?to 鈥?
First of all , thank you Matt for the tutorial. I learnt a lot.
But I think that UPDATE should also have post_save_redirect like Create Generic View. For me it did not work without that.
Best regards,
Lad.
W A R N I N G ! ! ! :: This Tutorial is VERY MUCH OUT OF DATE!!!
So what is out of day ? can we have an updated tutorial ?
This article may be slightly out-of-date, but it had far more useful examples on generic views to extrapolate from then the 鈥渙fficial documentation鈥?on the topic.
Matt, many thanks!
hi
Prompt how to get rid of advertising?
Cool gay butts are online now. Gay Butts shows its http://www.gay-butts.be butts collection just in Febrary!
gay cock hugeWatch these horny sluts taking it in the ass for the first time and getting their virgin butts ripped wide open.
hot blonde huge dildoIt鈥檚 an experience they will never forget. Frenzied 3some and wild anal actions caught on video are waiting here for you.