这样就可以自由的使用Django
# 获取数据
from .models import User
User.objects.all()
User.objects.count()
User.objects.filter(name='somenzz').count()
# 匹配,对应SQL:select * from User where name = 'somenzz'
User.objects.filter(name='somenzz')
# 不匹配,对应SQL:select * from User where name != 'somenzz'
User.objects.exclude(name='somenzz')
# 获取单条数据
user_123 = User.objects.get(id=123)
# 修改数据
user_123.age += 1
user_123.save()
python manage.py + 命令
来实现,比如常见的 python manage.py runserver
, python manage.py shell
。关键就在于 manage.py 文件,让我们来看一下 manage.py 的内容:#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_project.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_project.settings')
from django.conf import settings
settings.configure(DEBUG=True)
execute_from_command_line(sys.argv)
看看 Django 做了什么:def execute_from_command_line(argv=None):
"""Run a ManagementUtility."""
utility = ManagementUtility(argv)
utility.execute()
if settings.configured:
# Start the auto-reloading dev server even if the code is broken.
# The hardcoded condition is a code smell but we can't rely on a
# flag on the command class because we haven't located it yet.
if subcommand == 'runserver' and '--noreload' not in self.argv:
try:
autoreload.check_errors(django.setup)()
except Exception:
# The exception will be raised later in the child process
# started by the autoreloader. Pretend it didn't happen by
# loading an empty list of applications.
apps.all_models = defaultdict(dict)
apps.app_configs = {}
apps.apps_ready = apps.models_ready = apps.ready = True
# Remove options not compatible with the built-in runserver
# (e.g. options for the contrib.staticfiles' runserver).
# Changes here require manually testing as described in
# #27522.
_parser = self.fetch_command('runserver').create_parser('django', 'runserver')
_options, _args = _parser.parse_known_args(self.argv[2:])
for _arg in _args:
self.argv.remove(_arg)
# In all other cases, django.setup() is required to succeed.
else:
django.setup()
self.autocomplete()
django.setup()
会在 settings.configured 为真的情况下调用,至此已经真相大白。如果要想独立使用 Django,有两点是需要做的,一是配置 Django,二是调用执行 django.setup()
。setup 的作用就是加载设置并填充 Django 的应用程序注册表。setup 函数的代码如下:def setup(set_prefix=True):
"""
Configure the settings (this happens as a side effect of accessing the
first setting), configure logging and populate the app registry.
Set the thread-local urlresolvers script prefix if `set_prefix` is True.
"""
from django.apps import apps
from django.conf import settings
from django.urls import set_script_prefix
from django.utils.log import configure_logging
configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
if set_prefix:
set_script_prefix(
'/' if settings.FORCE_SCRIPT_NAME is None else settings.FORCE_SCRIPT_NAME
)
apps.populate(settings.INSTALLED_APPS)
import django
from django.conf import settings
settings.configure(
INSTALLED_APPS=["django_app.apps.DjangoAppConfig"],
DATABASES={
"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": "db.sqlite3",}
},
)
if __name__ == "__main__":
django.setup()
from django_app.models import CrawlerMonitor, DownloadedDocs
crawler_monitor = CrawlerMonitor.objects.get(id=1)
print(crawler_monitor.web_site)
django.setup()
仅当您的代码真正独立时才需要调用,因此,避免将可重用的应用程序逻辑放在独立的脚本中,如果实在无法避免的话,你可以这样做:if __name__ == '__main__':
import django
django.setup()
def fun1():
from django.core.mail import send_mail
# 一次发送一封邮件
send_mail(subject='爬虫id=xx发生异常', message='异常信息如下:xxx', from_email= 'somezz@***.com', recipient_list= ['somenzz@***.com'], fail_silently=False)
# 一次发送多封邮件
message1 = ('Subject here', 'Here is the message', 'from@example.com', ['first@example.com', 'other@example.com'])
message2 = ('Another Subject', 'Here is another message', 'from@example.com', ['second@test.com'])
send_mass_mail((message1, message2), fail_silently=False)
# send_mail 每次发邮件都会建立一个连接,发多封邮件时建立多个连接。而 send_mass_mail 是建立单个连接发送多封邮件,所以一次性发送多封邮件时 send_mass_mail 要优于 send_mail。
# 发送附件
def fun2():
from django.core.mail import EmailMessage
email = EmailMessage(
subject='Hello',
body= 'Body goes here',
from_email= 'somezz@***.com',
to= ['somezz@***.com', 'somenzz@***.com'],
)
email.attach_file("./demo_sendmail.py")
email.send()
EMAIL_USE_SSL = True
EMAIL_HOST = 'smtp.163.com'
EMAIL_PORT = 465
EMAIL_HOST_USER = '***@163.com'
EMAIL_HOST_PASSWORD = '***'
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
# 小于等于,<=,对应SQL:select * from User where id <= 724
User.objects.filter(id__lte=724)
# 同时大于和小于, 1 < id < 10,对应SQL:select * from User where id > 1 and id < 10
User.objects.filter(id__gt=1, id__lt=10)
# 包含,in,对应SQL:select * from User where id in (11,22,33)
User.objects.filter(id__in=[11, 22, 33])
# 为空:isnull=True,对应SQL:select * from User where pub_date is null
User.objects.filter(pub_date__isnull=True)
# 不匹配,大小写敏感,对应SQL:select * from User where name not like '%sre%',SQL中大小写不敏感
User.objects.exclude(name__contains="sre")
# 不匹配,大小写不敏感,对应SQL:select * from User where name not like '%sre%',SQL中大小写不敏感
User.objects.exclude(name__icontains="sre")
# 范围,between and,对应SQL:select * from User where id between 3 and 8
User.objects.filter(id__range=[3, 8])
# 以什么开头,大小写敏感,对应SQL:select * from User where name like 'sh%'
User.objects.filter(name__startswith='sre')
# 以什么开头,大小写不敏感,对应SQL:select * from User where name like 'sh%'
User.objects.filter(name__istartswith='sre')
# 排序,order by,正序,对应SQL:select * from User where name = 'somenzz' order by id
User.objects.filter(name='somenzz').order_by('id')
# 多级排序,order by,先按name进行正序排列,如果name一致则再按照id倒叙排列
User.objects.filter(name='somenzz').order_by('name','-id')
# 排序,order by,倒序,对应SQL:select * from User where name = 'somenzz' order by id desc
User.objects.filter(name='somenzz').order_by('-id')
# limit,对应SQL:select * from User limit 3;
User.objects.all()[:3]
# offset,取出结果的第10-20条数据(不包含10,包含20),也没有对应SQL,参考上边的SQL写法
User.objects.all()[10:20]
# 分组,group by,对应SQL:select username,count(1) from User group by username;
from django.db.models import Count
User.objects.values_list('username').annotate(Count('id'))
# 去重distinct,对应SQL:select distinct(username) from User
User.objects.values('username').distinct().count()
# filter多列、查询多列,对应SQL:select username,fullname from accounts_user
User.objects.values_list('username', 'fullname')
# filter单列、查询单列,正常values_list给出的结果是个列表,里边里边的每条数据对应一个元组,当只查询一列时,可以使用flat标签去掉元组,将每条数据的结果以字符串的形式存储在列表中,从而避免解析元组的麻烦
User.objects.values_list('username', flat=True)
# int字段取最大值、最小值、综合、平均数
from django.db.models import Sum,Count,Max,Min,Avg
User.objects.aggregate(Count('id'))
User.objects.aggregate(Sum('age'))
评论