在本章,我们将学习以下技巧: * 使用Django Shell * The monkey patching slugification function * The monkey patching model administration * Toggling Debug Toolbar * Using ThreadLocalMiddleware * Caching the method value * 通过电子邮件获取错误报告详情 * 使用 mod_wsgi 在Apache上部署项目 * 创建并使用Farbic部署脚本 ## 引言 In this chapter, we will go through several other important bits and pieces that will help you understand and utilize Django even better. You will get an overview of how to use the Django shell to experiment with the code before writing it into files. You will be introduced to monkey patching, also known as guerrilla patching, which is a powerful feature of dynamical languages such as Python, but should be used with moderation. You will learn how to debug your code and check its performance. Lastly, you will be taught how to deploy your Django project on a dedicated server. ## 使用Django shell With the virtual environment activated and your project directory selected as the current directory, enter this command into your command-line tool: ```python (myproject_env)$ python manage shell ``` By executing the preceding command, you get into an interactive Python shell configured for your Django project, where you can play around with the code and inspect classes, try out methods, or execute scripts on the fly. In this recipe, we will go through the most important functions you need to know to work with the Django shell. ## 准备开始 Optionally, you can install IPython or bpython using one of the following commands, which will highlight the syntax for the output of your Django shell: ```python (myproject_env)$ pip install ipython (myproject_env)$ pip install bpython ``` ## 具体实现过程 你可以通过下面的这些说明学习到Django shell的使用基础: 1. 输入下面的命令以运行Django shell: ```python (myproject_env)$ python manage shell ``` The prompt will change to In [1]: or >>> depending on whether you use IPython or not. Now you can import classes, functions, or variables and play around with them. For example, to see the version of an installed module, you can import the module and then try to read its __version__, VERSION, or version variables: ```python >>> import MySQLdb >>> MySQLdb.__version__ '1.2.3' ``` To get a comprehensive description of a module, class, function, method, keyword, or documentation topic, use the help function. You can either pass a string with the path to a specific entity, or the entity itself, as follows: ```python >>> help('django.forms') ``` This will open the help page for the django.forms module. Use the arrow keys to scroll the page up and down. Press Q to get back to the shell. This is an example of passing an entity to the help function. This will open a help page for the ModelForm class: ```python >>> from django.forms import ModelForm >>> help(ModelForm) ``` To quickly see what fields and values are available for a model instance, use the __dict__ attribute. Also use the pprint function to get dictionaries printed in a more readable format (not just one long line): ```python >>> from pprint import pprint >>> from django.contrib.contenttypes.models import ContentType >>> pprint(ContentType.objects.all()[0].__dict__) {'_state': <django.db.models.base.ModelState object at 0x10756d250>, 'app_label': u'bulletin_board', 'id': 11, 'model': u'bulletin', 'name': u'Bulletin'} ``` Note that by using this method, we don't get many-to-many relationships. But this might be enough for a quick overview of the fields and values. To get all the available properties and methods of an object, you can use the dir function, as follows: ```python >>> dir(ContentType()) ['DoesNotExist', 'MultipleObjectsReturned', '__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', u'__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__', '__weakref__', '_base_manager', '_default_manager', '_deferred', '_do_insert', '_do_update', '_get_FIELD_display', '_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val', '_get_unique_checks', '_meta', '_perform_date_checks', '_perform_unique_checks', '_save_parents', '_save_table', '_set_pk_val', '_state', 'app_label', 'clean', 'clean_fields', 'content_type_set_for_comment', 'date_error_message', 'delete', 'full_clean', 'get_all_objects_for_this_type', 'get_object_for_this_type', 'id', 'logentry_set', 'model', 'model_class', 'name', 'natural_key', 'objects', 'permis‘ ’sion_set', 'pk', 'prepare_database_save', 'save', 'save_base', 'serializable_value', 'unique_error_message', 'validate_unique'] ``` The Django shell is useful for experimenting with QuerySets or regular expressions before putting them into your model methods, views, or management commands. For example, to check the e-mail-validation regular expression, you can type this into the Django shell: ```python >>> import re >>> email_pattern = re.compile(r'[^@]+@[^@]+\.[^@]+') >>> email_pattern.match('aidas@bendoraitis.lt') <_sre.SRE_Match object at 0x1075681d0> ``` To exit the Django shell, press Ctrl + D or type the following command: >>> exit() ## 工作原理 The difference between a normal Python shell and the Django shell is that when you run the Django shell, manage.py sets the DJANGO_SETTINGS_MODULE environment variable to the project's settings path, and then Django gets set up. So, all database queries, templates, URL configuration, or anything else are handled within the context of your project. ## 参见 *The The monkey patching slugification function recipe* *The The monkey patching model administration recipe* ## The monkey patching slugification function *Monkey patching or guerrilla patching* is a piece of code that extends or modifies another piece of code at runtime. It is not recommended to use monkey patching often, but sometimes it is the only possible way to fix a bug in third-party modules without creating a separate branch of the module, or to prepare unit tests for testing without using complex database manipulations. In this recipe, you will learn how to exchange the default slugify function with the third-party awesome-slugify module, which handles German, Greek, and Russian words smarter and also allows custom slugification for other languages. The slugify function is used to create a URL-friendly version of the object's title or the uploaded filename: it strips the leading and trailing whitespace, converts the text to lowercase, removes nonword characters, and converts spaces to hyphens.