标签归档:Django

设置预定的工作?

问题:设置预定的工作?

我一直在使用Django开发Web应用程序,并且很好奇是否有一种方法可以安排作业定期运行。

基本上,我只想遍历数据库并自动定期进行一些计算/更新,但是我似乎找不到任何有关此操作的文档。

有人知道如何设置吗?

需要说明的是:我知道我可以为此设置cron工作,但我很好奇Django中是否有某些功能可以提供此功能。我希望人们能够自己部署此应用程序,而无需进行大量配置(最好为零)。

我已经考虑过通过简单地检查自从上次将请求发送到站点以来是否应该运行作业来“追溯地”触发这些操作,但是我希望有一些清洁的方法。

I’ve been working on a web app using Django, and I’m curious if there is a way to schedule a job to run periodically.

Basically I just want to run through the database and make some calculations/updates on an automatic, regular basis, but I can’t seem to find any documentation on doing this.

Does anyone know how to set this up?

To clarify: I know I can set up a cron job to do this, but I’m curious if there is some feature in Django that provides this functionality. I’d like people to be able to deploy this app themselves without having to do much config (preferably zero).

I’ve considered triggering these actions “retroactively” by simply checking if a job should have been run since the last time a request was sent to the site, but I’m hoping for something a bit cleaner.


回答 0

我采用的一种解决方案是这样做:

1)创建一个自定义管理命令,例如

python manage.py my_cool_command

2)使用cron(在Linux上)或at在要求的时间(在Windows上)运行我的命令。

这是一个简单的解决方案,不需要安装沉重的AMQP堆栈。但是,使用其他答案中提到的诸如Celery之类的东西有很好的优势。特别是,使用Celery很好,不必将应用程序逻辑散布到crontab文件中。但是,cron解决方案非常适合中小型应用程序,并且您不需要太多外部依赖项。

编辑:

在更高版本的Windows中,at不建议在Windows 8,Server 2012及更高版本中使用该命令。您可以使用schtasks.exe相同的用途。

****更新****这是django doc 的新链接,用于编写自定义管理命令

One solution that I have employed is to do this:

1) Create a custom management command, e.g.

python manage.py my_cool_command

2) Use cron (on Linux) or at (on Windows) to run my command at the required times.

This is a simple solution that doesn’t require installing a heavy AMQP stack. However there are nice advantages to using something like Celery, mentioned in the other answers. In particular, with Celery it is nice to not have to spread your application logic out into crontab files. However the cron solution works quite nicely for a small to medium sized application and where you don’t want a lot of external dependencies.

EDIT:

In later version of windows the at command is deprecated for Windows 8, Server 2012 and above. You can use schtasks.exe for same use.

**** UPDATE **** This the new link of django doc for writing the custom management command


回答 1

Celery是基于AMQP(RabbitMQ)构建的分布式任务队列。它还以cron类的方式处理周期性任务(请参阅周期性任务)。根据您的应用程序,可能值得一试。

用django(docs)设置Celery非常容易,并且在停机的情况下,定期任务实际上会跳过错过的任务。如果任务失败,Celery还具有内置的重试机制。

Celery is a distributed task queue, built on AMQP (RabbitMQ). It also handles periodic tasks in a cron-like fashion (see periodic tasks). Depending on your app, it might be worth a gander.

Celery is pretty easy to set up with django (docs), and periodic tasks will actually skip missed tasks in case of a downtime. Celery also has built-in retry mechanisms, in case a task fails.


回答 2

我们已经开源了我认为是结构化应用程序的源代码。Brian的解决方案也暗指。我们希望收到任何/所有反馈!

https://github.com/tivix/django-cron

它带有一个管理命令:

./manage.py runcrons

做到了。每个cron都被建模为一个类(因此其所有OO),并且每个cron都以不同的频率运行,并且我们确保相同cron类型不会并行运行(以防万一cron自身花费的时间比其频率更长!)

We’ve open-sourced what I think is a structured app. that Brian’s solution above alludes too. We would love any / all feedback!

https://github.com/tivix/django-cron

It comes with one management command:

./manage.py runcrons

That does the job. Each cron is modeled as a class (so its all OO) and each cron runs at a different frequency and we make sure the same cron type doesn’t run in parallel (in case crons themselves take longer time to run than their frequency!)


回答 3

如果您使用的是标准POSIX操作系统,请使用cron

如果您使用的是Windows,请

编写Django管理命令以

  1. 找出他们使用的平台。

  2. 为您的用户执行适当的“ AT”命令,为您的用户更新crontab。

If you’re using a standard POSIX OS, you use cron.

If you’re using Windows, you use at.

Write a Django management command to

  1. Figure out what platform they’re on.

  2. Either execute the appropriate “AT” command for your users, or update the crontab for your users.


回答 4

有趣的新可插拔Django应用:django-chronograph

您只需要添加一个用作计时器的cron条目,即可在脚本中运行一个非常漂亮的Django管理界面。

Interesting new pluggable Django app: django-chronograph

You only have to add one cron entry which acts as a timer, and you have a very nice Django admin interface into the scripts to run.


回答 5

看一下Django Poor Man’s Cron,这是一个Django应用,它利用垃圾邮件搜索引擎,搜索引擎索引机器人等以大致固定的时间间隔运行计划的任务

请参阅:http : //code.google.com/p/django-poormanscron/

Look at Django Poor Man’s Cron which is a Django app that makes use of spambots, search engine indexing robots and alike to run scheduled tasks in approximately regular intervals

See: http://code.google.com/p/django-poormanscron/


回答 6

布赖恩·尼尔(Brian Neal)建议通过cron运行管理命令效果很好,但是如果您正在寻找更强大的功能(但还不如Celery(Celery)那么细腻),我可以考虑一下Kronos这样的库:

# app/cron.py

import kronos

@kronos.register('0 * * * *')
def task():
    pass

Brian Neal’s suggestion of running management commands via cron works well, but if you’re looking for something a little more robust (yet not as elaborate as Celery) I’d look into a library like Kronos:

# app/cron.py

import kronos

@kronos.register('0 * * * *')
def task():
    pass

回答 7

RabbitMQ和Celery比Cron具有更多的功能和任务处理功能。如果任务失败不是问题,并且您认为您将在下一个调用中处理损坏的任务,那么Cron就足够了。

Celery & AMQP将让您处理损坏的任务,并且它将由另一位工作人员再次执行(Celery工作人员侦听要处理的下一个任务),直到到达任务的max_retries属性为止。您甚至可以在发生故障时调用任务,例如记录故障,或在发生故障后向管理员发送电子邮件max_retries

而且,当您需要扩展应用程序时,您可以分发Celery和AMQP服务器。

RabbitMQ and Celery have more features and task handling capabilities than Cron. If task failure isn’t an issue, and you think you will handle broken tasks in the next call, then Cron is sufficient.

Celery & AMQP will let you handle the broken task, and it will get executed again by another worker (Celery workers listen for the next task to work on), until the task’s max_retries attribute is reached. You can even invoke tasks on failure, like logging the failure, or sending an email to the admin once the max_retries has been reached.

And you can distribute Celery and AMQP servers when you need to scale your application.


回答 8

我之前有完全相同的要求,最终使用APScheduler用户指南)解决了这一要求

它使调度作业变得非常简单,并使它独立于某些代码的基于请求的执行。以下是一个简单的示例。

from apscheduler.schedulers.background import BackgroundScheduler

scheduler = BackgroundScheduler()
job = None

def tick():
    print('One tick!')\

def start_job():
    global job
    job = scheduler.add_job(tick, 'interval', seconds=3600)
    try:
        scheduler.start()
    except:
        pass

希望这对某人有帮助!

I had exactly the same requirement a while ago, and ended up solving it using APScheduler (User Guide)

It makes scheduling jobs super simple, and keeps it independent for from request-based execution of some code. Following is a simple example.

from apscheduler.schedulers.background import BackgroundScheduler

scheduler = BackgroundScheduler()
job = None

def tick():
    print('One tick!')\

def start_job():
    global job
    job = scheduler.add_job(tick, 'interval', seconds=3600)
    try:
        scheduler.start()
    except:
        pass

Hope this helps somebody!


回答 9

我个人使用cron,但是django-extensionsJobs Scheduling部分看起来很有趣。

I personally use cron, but the Jobs Scheduling parts of django-extensions looks interesting.


回答 10

尽管不是Django的一部分,但Airflow是一个较新的项目(截至2016年),对任务管理很有用。

Airflow是一个工作流自动化和调度系统,可用于创作和管理数据管道。基于Web的UI为开发人员提供了一系列用于管理和查看这些管道的选项。

Airflow用Python编写,并使用Flask构建。

Airflow由Airbnb的Maxime Beauchemin创建,并于2015年春季开源。它于2016年冬季加入Apache Software Foundation的孵化计划。这是Git项目页面和一些其他背景信息

Although not part of Django, Airflow is a more recent project (as of 2016) that is useful for task management.

Airflow is a workflow automation and scheduling system that can be used to author and manage data pipelines. A web-based UI provides the developer with a range of options for managing and viewing these pipelines.

Airflow is written in Python and is built using Flask.

Airflow was created by Maxime Beauchemin at Airbnb and open sourced in the spring of 2015. It joined the Apache Software Foundation’s incubation program in the winter of 2016. Here is the Git project page and some addition background information.


回答 11

将以下内容放在cron.py文件的顶部:

#!/usr/bin/python
import os, sys
sys.path.append('/path/to/') # the parent directory of the project
sys.path.append('/path/to/project') # these lines only needed if not on path
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproj.settings'

# imports and code below

Put the following at the top of your cron.py file:

#!/usr/bin/python
import os, sys
sys.path.append('/path/to/') # the parent directory of the project
sys.path.append('/path/to/project') # these lines only needed if not on path
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproj.settings'

# imports and code below

回答 12

我只是想到了这个相当简单的解决方案:

  1. 定义一个视图函数do_work(req,param),就像在其他任何视图中一样,通过URL映射,返回HttpResponse等。
  2. 根据您的时间偏好设置(或在Windows中使用AT或计划任务)设置cron作业,该作业运行curl http:// localhost / your / mapped / url?param = value

您可以添加参数,但只需将参数添加到URL。

跟我说你们的想法。

[更新]我现在正在使用来自django-extensions的 runjob命令,而不是curl。

我的cron看起来像这样:

@hourly python /path/to/project/manage.py runjobs hourly

…等等,每天,每月等。您也可以将其设置为运行特定作业。

我发现它更易于管理和清洁。不需要将URL映射到视图。只需定义您的工作类别和crontab即可。

I just thought about this rather simple solution:

  1. Define a view function do_work(req, param) like you would with any other view, with URL mapping, return a HttpResponse and so on.
  2. Set up a cron job with your timing preferences (or using AT or Scheduled Tasks in Windows) which runs curl http://localhost/your/mapped/url?param=value.

You can add parameters but just adding parameters to the URL.

Tell me what you guys think.

[Update] I’m now using runjob command from django-extensions instead of curl.

My cron looks something like this:

@hourly python /path/to/project/manage.py runjobs hourly

… and so on for daily, monthly, etc’. You can also set it up to run a specific job.

I find it more managable and a cleaner. Doesn’t require mapping a URL to a view. Just define your job class and crontab and you’re set.


回答 13

在代码部分之后,我可以写任何东西,就像我的views.py :)

#######################################
import os,sys
sys.path.append('/home/administrator/development/store')
os.environ['DJANGO_SETTINGS_MODULE']='store.settings'
from django.core.management impor setup_environ
from store import settings
setup_environ(settings)
#######################################

来自 http://www.cotellese.net/2007/09/27/running-external-scripts-against-django-models/

after the part of code,I can write anything just like my views.py :)

#######################################
import os,sys
sys.path.append('/home/administrator/development/store')
os.environ['DJANGO_SETTINGS_MODULE']='store.settings'
from django.core.management impor setup_environ
from store import settings
setup_environ(settings)
#######################################

from http://www.cotellese.net/2007/09/27/running-external-scripts-against-django-models/


回答 14

您绝对应该检查django-q!它不需要任何额外的配置,并且很可能具有处理商业项目中任何生产问题所需的一切。

它是积极开发的,并且与django,django ORM,mongo,redis很好地集成在一起。这是我的配置:

# django-q
# -------------------------------------------------------------------------
# See: http://django-q.readthedocs.io/en/latest/configure.html
Q_CLUSTER = {
    # Match recommended settings from docs.
    'name': 'DjangoORM',
    'workers': 4,
    'queue_limit': 50,
    'bulk': 10,
    'orm': 'default',

# Custom Settings
# ---------------
# Limit the amount of successful tasks saved to Django.
'save_limit': 10000,

# See https://github.com/Koed00/django-q/issues/110.
'catch_up': False,

# Number of seconds a worker can spend on a task before it's terminated.
'timeout': 60 * 5,

# Number of seconds a broker will wait for a cluster to finish a task before presenting it again. This needs to be
# longer than `timeout`, otherwise the same task will be processed multiple times.
'retry': 60 * 6,

# Whether to force all async() calls to be run with sync=True (making them synchronous).
'sync': False,

# Redirect worker exceptions directly to Sentry error reporter.
'error_reporter': {
    'sentry': RAVEN_CONFIG,
},
}

You should definitely check out django-q! It requires no additional configuration and has quite possibly everything needed to handle any production issues on commercial projects.

It’s actively developed and integrates very well with django, django ORM, mongo, redis. Here is my configuration:

# django-q
# -------------------------------------------------------------------------
# See: http://django-q.readthedocs.io/en/latest/configure.html
Q_CLUSTER = {
    # Match recommended settings from docs.
    'name': 'DjangoORM',
    'workers': 4,
    'queue_limit': 50,
    'bulk': 10,
    'orm': 'default',

# Custom Settings
# ---------------
# Limit the amount of successful tasks saved to Django.
'save_limit': 10000,

# See https://github.com/Koed00/django-q/issues/110.
'catch_up': False,

# Number of seconds a worker can spend on a task before it's terminated.
'timeout': 60 * 5,

# Number of seconds a broker will wait for a cluster to finish a task before presenting it again. This needs to be
# longer than `timeout`, otherwise the same task will be processed multiple times.
'retry': 60 * 6,

# Whether to force all async() calls to be run with sync=True (making them synchronous).
'sync': False,

# Redirect worker exceptions directly to Sentry error reporter.
'error_reporter': {
    'sentry': RAVEN_CONFIG,
},
}

回答 15

用于计划程序作业的Django APScheduler。Advanced Python Scheduler(APScheduler)是一个Python库,可让您安排Python代码稍后执行,一次或定期执行。您可以根据需要随时添加或删除旧作业。

注意:我是这个图书馆的作者

安装APScheduler

pip install apscheduler

查看文件功能调用

文件名:scheduler_jobs.py

def FirstCronTest():
    print("")
    print("I am executed..!")

配置调度程序

制作execute.py文件并添加以下代码

from apscheduler.schedulers.background import BackgroundScheduler
scheduler = BackgroundScheduler()

您的书面函数在这里,调度程序函数写在scheduler_jobs中

import scheduler_jobs 

scheduler.add_job(scheduler_jobs.FirstCronTest, 'interval', seconds=10)
scheduler.start()

链接文件以执行

现在,在Url文件底部添加以下行

import execute

Django APScheduler for Scheduler Jobs. Advanced Python Scheduler (APScheduler) is a Python library that lets you schedule your Python code to be executed later, either just once or periodically. You can add new jobs or remove old ones on the fly as you please.

note: I’m the author of this library

Install APScheduler

pip install apscheduler

View file function to call

file name: scheduler_jobs.py

def FirstCronTest():
    print("")
    print("I am executed..!")

Configuring the scheduler

make execute.py file and add the below codes

from apscheduler.schedulers.background import BackgroundScheduler
scheduler = BackgroundScheduler()

Your written functions Here, the scheduler functions are written in scheduler_jobs

import scheduler_jobs 

scheduler.add_job(scheduler_jobs.FirstCronTest, 'interval', seconds=10)
scheduler.start()

Link the File for Execution

Now, add the below line in the bottom of Url file

import execute

回答 16

我今天对你的问题也有类似的看法。

我不想让它通过服务器cron来处理(最后,大多数库只是cron助手)。

因此,我创建了一个调度模块并将其附加到init

这不是最好的方法,但是它可以帮助我将所有代码都放在一个地方,并且其执行与主应用程序有关。

I had something similar with your problem today.

I didn’t wanted to have it handled by the server trhough cron (and most of the libs were just cron helpers in the end).

So i’ve created a scheduling module and attached it to the init .

It’s not the best approach, but it helps me to have all the code in a single place and with its execution related to the main app.


回答 17

是的,上面的方法很棒。我尝试了其中一些。最后,我发现了这样的方法:

    from threading import Timer

    def sync():

        do something...

        sync_timer = Timer(self.interval, sync, ())
        sync_timer.start()

就像递归一样。

好的,我希望这种方法可以满足您的要求。:)

Yes, the method above is so great. And I tried some of them. At last, I found a method like this:

    from threading import Timer

    def sync():

        do something...

        sync_timer = Timer(self.interval, sync, ())
        sync_timer.start()

Just like Recursive.

Ok, I hope this method can meet your requirement. :)


回答 18

与Celery相比,更现代的解决方案是Django Q:https//django-q.readthedocs.io/en/latest/index.html

它具有出色的文档,并且很容易理解。缺少Windows支持,因为Windows不支持流程分支。但是,如果您使用Windows for Linux子系统创建开发环境,则效果很好。

A more modern solution (compared to Celery) is Django Q: https://django-q.readthedocs.io/en/latest/index.html

It has great documentation and is easy to grok. Windows support is lacking, because Windows does not support process forking. But it works fine if you create your dev environment using the Windows for Linux Subsystem.


回答 19

我用Celery做我的定期任务。首先,您需要按以下步骤安装它:

pip install django-celery

不要忘记注册django-celery设置,然后您可以执行以下操作:

from celery import task
from celery.decorators import periodic_task
from celery.task.schedules import crontab
from celery.utils.log import get_task_logger
@periodic_task(run_every=crontab(minute="0", hour="23"))
def do_every_midnight():
 #your code

I use celery to create my periodical tasks. First you need to install it as follows:

pip install django-celery

Don’t forget to register django-celery in your settings and then you could do something like this:

from celery import task
from celery.decorators import periodic_task
from celery.task.schedules import crontab
from celery.utils.log import get_task_logger
@periodic_task(run_every=crontab(minute="0", hour="23"))
def do_every_midnight():
 #your code

回答 20

我不确定这对任何人都有用,因为我必须提供系统的其他用户来计划作业,而又不让他们访问实际的服务器(Windows)任务计划程序,因此我创建了这个可重用的应用程序。

请注意,用户可以访问服务器上的一个共享文件夹,可以在其中创建所需的command / task / .bat文件。然后可以使用此应用安排此任务。

应用名称为 Django_Windows_Scheduler

屏幕截图: 在此处输入图片说明

I am not sure will this be useful for anyone, since I had to provide other users of the system to schedule the jobs, without giving them access to the actual server(windows) Task Scheduler, I created this reusable app.

Please note users have access to one shared folder on server where they can create required command/task/.bat file. This task then can be scheduled using this app.

App name is Django_Windows_Scheduler

ScreenShot: enter image description here


回答 21

如果您想要比Celery可靠的产品,请尝试构建在AWS SQS / SNS之上的TaskHawk

请参阅:http : //taskhawk.readthedocs.io

If you want something more reliable than Celery, try TaskHawk which is built on top of AWS SQS/SNS.

Refer: http://taskhawk.readthedocs.io


回答 22

对于简单的dockerized项目,我真的看不到任何现有的合适答案。

因此,我写了一个非常准系统的解决方案,不需要外部库或触发器,它们可以独立运行。无需外部os-cron,就可以在每种环境下工作。

它通过添加中间件来工作: middleware.py

import threading

def should_run(name, seconds_interval):
    from application.models import CronJob
    from django.utils.timezone import now

    try:
        c = CronJob.objects.get(name=name)
    except CronJob.DoesNotExist:
        CronJob(name=name, last_ran=now()).save()
        return True

    if (now() - c.last_ran).total_seconds() >= seconds_interval:
        c.last_ran = now()
        c.save()
        return True

    return False


class CronTask:
    def __init__(self, name, seconds_interval, function):
        self.name = name
        self.seconds_interval = seconds_interval
        self.function = function


def cron_worker(*_):
    if not should_run("main", 60):
        return

    # customize this part:
    from application.models import Event
    tasks = [
        CronTask("events", 60 * 30, Event.clean_stale_objects),
        # ...
    ]

    for task in tasks:
        if should_run(task.name, task.seconds_interval):
            task.function()


def cron_middleware(get_response):

    def middleware(request):
        response = get_response(request)
        threading.Thread(target=cron_worker).start()
        return response

    return middleware

models/cron.py

from django.db import models


class CronJob(models.Model):
    name = models.CharField(max_length=10, primary_key=True)
    last_ran = models.DateTimeField()

settings.py

MIDDLEWARE = [
    ...
    'application.middleware.cron_middleware',
    ...
]

For simple dockerized projects, I could not really see any existing answer fit.

So I wrote a very barebones solution without the need of external libraries or triggers, which runs on its own. No external os-cron needed, should work in every environment.

It works by adding a middleware: middleware.py

import threading

def should_run(name, seconds_interval):
    from application.models import CronJob
    from django.utils.timezone import now

    try:
        c = CronJob.objects.get(name=name)
    except CronJob.DoesNotExist:
        CronJob(name=name, last_ran=now()).save()
        return True

    if (now() - c.last_ran).total_seconds() >= seconds_interval:
        c.last_ran = now()
        c.save()
        return True

    return False


class CronTask:
    def __init__(self, name, seconds_interval, function):
        self.name = name
        self.seconds_interval = seconds_interval
        self.function = function


def cron_worker(*_):
    if not should_run("main", 60):
        return

    # customize this part:
    from application.models import Event
    tasks = [
        CronTask("events", 60 * 30, Event.clean_stale_objects),
        # ...
    ]

    for task in tasks:
        if should_run(task.name, task.seconds_interval):
            task.function()


def cron_middleware(get_response):

    def middleware(request):
        response = get_response(request)
        threading.Thread(target=cron_worker).start()
        return response

    return middleware

models/cron.py:

from django.db import models


class CronJob(models.Model):
    name = models.CharField(max_length=10, primary_key=True)
    last_ran = models.DateTimeField()

settings.py:

MIDDLEWARE = [
    ...
    'application.middleware.cron_middleware',
    ...
]

回答 23

简单的方法是编写一个自定义的shell命令(请参阅Django文档)并在Linux上使用cronjob执行它。但是,我强烈建议您使用像RabbitMQ这样的消息代理以及Celery。也许你可以看看这个教程

Simple way is to write a custom shell command see Django Documentation and execute it using a cronjob on linux. However i would highly recommend using a message broker like RabbitMQ coupled with celery. Maybe you can have a look at this Tutorial


django中业务逻辑和数据访问的分离

问题:django中业务逻辑和数据访问的分离

我正在Django中编写一个项目,并且看到80%的代码在file中models.py。这段代码令人困惑,并且在一段时间之后,我不再了解实际发生的事情。

这是困扰我的事情:

  1. 我发现模型级别(应该只负责处理数据库中的数据)在发送电子邮件,使用API​​到其他服务等方面也很丑陋。
  2. 另外,我发现在视图中放置业务逻辑也是不可接受的,因为这样很难控制。例如,在我的应用程序中,至少有三种方法来创建的新实例User,但从技术上讲,它应统一创建它们。
  3. 我并不总是注意到模型的方法和属性何时变得不确定,以及何时出现副作用。

这是一个简单的例子。首先,User模型是这样的:

class User(db.Models):

    def get_present_name(self):
        return self.name or 'Anonymous'

    def activate(self):
        self.status = 'activated'
        self.save()

随着时间的流逝,它变成了:

class User(db.Models):

    def get_present_name(self): 
        # property became non-deterministic in terms of database
        # data is taken from another service by api
        return remote_api.request_user_name(self.uid) or 'Anonymous' 

    def activate(self):
        # method now has a side effect (send message to user)
        self.status = 'activated'
        self.save()
        send_mail('Your account is activated!', '…', [self.email])

我想要的是在代码中分离实体:

  1. 数据库级别的数据库实体:什么包含我的应用程序?
  2. 我的应用程序的实体,业务逻辑级别:可以使我的应用程序做什么?

有什么好的实践来实现可以在Django中应用的方法?

I am writing a project in Django and I see that 80% of the code is in the file models.py. This code is confusing and, after a certain time, I cease to understand what is really happening.

Here is what bothers me:

  1. I find it ugly that my model level (which was supposed to be responsible only for the work with data from a database) is also sending email, walking on API to other services, etc.
  2. Also, I find it unacceptable to place business logic in the view, because this way it becomes difficult to control. For example, in my application there are at least three ways to create new instances of User, but technically it should create them uniformly.
  3. I do not always notice when the methods and properties of my models become non-deterministic and when they develop side effects.

Here is a simple example. At first, the User model was like this:

class User(db.Models):

    def get_present_name(self):
        return self.name or 'Anonymous'

    def activate(self):
        self.status = 'activated'
        self.save()

Over time, it turned into this:

class User(db.Models):

    def get_present_name(self): 
        # property became non-deterministic in terms of database
        # data is taken from another service by api
        return remote_api.request_user_name(self.uid) or 'Anonymous' 

    def activate(self):
        # method now has a side effect (send message to user)
        self.status = 'activated'
        self.save()
        send_mail('Your account is activated!', '…', [self.email])

What I want is to separate entities in my code:

  1. Entities of my database, database level: What contains my application?
  2. Entities of my application, business logic level: What can make my application?

What are the good practices to implement such an approach that can be applied in Django?


回答 0

似乎您是在询问数据模型域模型 –后者是您可以找到最终用户感知的业务逻辑和实体的地方,前者是您实际存储数据的地方。

此外,我将问题的第三部分解释为:如何注意到未能将这些模型分开的问题。

这是两个截然不同的概念,很难将它们分开。但是,有一些常见的模式和工具可用于此目的。

关于领域模型

您需要认识的第一件事是您的域模型并不是真正的数据。它涉及诸如“激活此用户”,“停用此用户”,“当前已激活哪些用户”和“该用户的名字是什么”之类的动作问题。用经典术语来说:它是关于查询命令的

指挥思维

让我们从示例中的命令开始:“激活此用户”和“停用此用户”。关于命令的好处是,它们可以很容易地用小给定的情况来表示:


管理员激活该用户时,将其指定为非活动用户
该用户将变为活动状态
并向该用户发送确认电子邮件,
并将条目添加到系统日志
(等)。

这种情况对于查看单个命令如何影响基础结构的不同部分很有用,在这种情况下,您的数据库(某种“活动”标志),邮件服务器,系统日志等会受到影响。

这样的场景也确实可以帮助您设置测试驱动开发环境。

最后,思考命令确实可以帮助您创建面向任务的应用程序。您的用户将对此表示赞赏:-)

表达命令

Django提供了两种简单的表达命令的方式:它们都是有效的选择,并且将两种方法混合使用并不罕见。

服务层

服务模块已经通过@Hedde描述。在这里,您定义了一个单独的模块,每个命令都表示为一个函数。

services.py

def activate_user(user_id):
    user = User.objects.get(pk=user_id)

    # set active flag
    user.active = True
    user.save()

    # mail user
    send_mail(...)

    # etc etc

使用表格

另一种方法是为每个命令使用Django表单。我更喜欢这种方法,因为它结合了多个紧密相关的方面:

  • 命令的执行(它做什么?)
  • 验证命令参数(可以执行此操作吗?)
  • 命令演示(如何执行此操作?)

表格

class ActivateUserForm(forms.Form):

    user_id = IntegerField(widget = UsernameSelectWidget, verbose_name="Select a user to activate")
    # the username select widget is not a standard Django widget, I just made it up

    def clean_user_id(self):
        user_id = self.cleaned_data['user_id']
        if User.objects.get(pk=user_id).active:
            raise ValidationError("This user cannot be activated")
        # you can also check authorizations etc. 
        return user_id

    def execute(self):
        """
        This is not a standard method in the forms API; it is intended to replace the 
        'extract-data-from-form-in-view-and-do-stuff' pattern by a more testable pattern. 
        """
        user_id = self.cleaned_data['user_id']

        user = User.objects.get(pk=user_id)

        # set active flag
        user.active = True
        user.save()

        # mail user
        send_mail(...)

        # etc etc

在查询中思考

您的示例不包含任何查询,因此我自由地编写了一些有用的查询。我更喜欢使用“问题”一词,但是查询是经典的术语。有趣的查询是:“此用户的名称是什么?”,“此用户可以登录吗?”,“向我显示已停用用户的列表”和“已停用用户的地理分布是什么?”。

在着手回答这些查询之前,您应该始终问自己两个问题:这是仅针对我的模板的表示性查询,和/或与执行我的命令相关的业务逻辑查询,和/或报告查询。

呈现查询只是为了改善用户界面。业务逻辑查询的答案直接影响命令的执行。报告查询仅用于分析目的,并且具有较宽松的时间限制。这些类别不是互相排斥的。

另一个问题是:“我是否完全控制答案?” 例如,在查询用户名(在这种情况下)时,我们对结果没有任何控制权,因为我们依赖于外部API。

进行查询

Django中最基本的查询是使用Manager对象:

User.objects.filter(active=True)

当然,这仅在数据实际在数据模型中表示时才有效。这并非总是如此。在这种情况下,您可以考虑以下选项。

自定义标签和过滤器

第一种替代方法仅对表示性查询有用:自定义标记和模板过滤器。

template.html

<h1>Welcome, {{ user|friendly_name }}</h1>

template_tags.py

@register.filter
def friendly_name(user):
    return remote_api.get_cached_name(user.id)

查询方法

如果您的查询不只是表示形式的查询,则可以将查询添加到您的services.py(如果正在使用的话),或者引入querys.py模块:

querys.py

def inactive_users():
    return User.objects.filter(active=False)


def users_called_publysher():
    for user in User.objects.all():
        if remote_api.get_cached_name(user.id) == "publysher":
            yield user 

代理模型

代理模型在业务逻辑和报告的上下文中非常有用。您基本上定义了模型的增强子集。您可以通过覆盖Manager的基本QuerySet来覆盖Manager.get_queryset()方法。

models.py

class InactiveUserManager(models.Manager):
    def get_queryset(self):
        query_set = super(InactiveUserManager, self).get_queryset()
        return query_set.filter(active=False)

class InactiveUser(User):
    """
    >>> for user in InactiveUser.objects.all():
    …        assert user.active is False 
    """

    objects = InactiveUserManager()
    class Meta:
        proxy = True

查询模型

对于本质上很复杂但经常执行的查询,存在查询模型的可能性。查询模型是非规范化的一种形式,其中单个查询的相关数据存储在单独的模型中。当然,技巧是使非规范化模型与主模型保持同步。仅当更改完全在您的控制之下时才能使用查询模型。

models.py

class InactiveUserDistribution(models.Model):
    country = CharField(max_length=200)
    inactive_user_count = IntegerField(default=0)

第一种选择是在命令中更新这些模型。如果仅通过一个或两个命令更改这些模型,这将非常有用。

表格

class ActivateUserForm(forms.Form):
    # see above

    def execute(self):
        # see above
        query_model = InactiveUserDistribution.objects.get_or_create(country=user.country)
        query_model.inactive_user_count -= 1
        query_model.save()

更好的选择是使用自定义信号。这些信号当然是由您的命令发出的。信号的优点是您可以使多个查询模型与原始模型保持同步。此外,可以使用Celery或类似框架将信号处理任务转移给后台任务。

signal.py

user_activated = Signal(providing_args = ['user'])
user_deactivated = Signal(providing_args = ['user'])

表格

class ActivateUserForm(forms.Form):
    # see above

    def execute(self):
        # see above
        user_activated.send_robust(sender=self, user=user)

models.py

class InactiveUserDistribution(models.Model):
    # see above

@receiver(user_activated)
def on_user_activated(sender, **kwargs):
        user = kwargs['user']
        query_model = InactiveUserDistribution.objects.get_or_create(country=user.country)
        query_model.inactive_user_count -= 1
        query_model.save()

保持清洁

使用这种方法时,很容易确定代码是否保持干净。只需遵循以下准则:

  • 我的模型中是否包含比管理数据库状态还执行更多功能的方法?您应该提取命令。
  • 我的模型是否包含未映射到数据库字段的属性?您应该提取一个查询。
  • 我的模型是否引用了不是数据库的基础架构(例如邮件)?您应该提取命令。

视图也一样(因为视图经常遇到相同的问题)。

  • 我的视图是否主动管理数据库模型?您应该提取命令。

一些参考

Django文档:代理模型

Django文档:信号

体系结构:域驱动设计

It seems like you are asking about the difference between the data model and the domain model – the latter is where you can find the business logic and entities as perceived by your end user, the former is where you actually store your data.

Furthermore, I’ve interpreted the 3rd part of your question as: how to notice failure to keep these models separate.

These are two very different concepts and it’s always hard to keep them separate. However, there are some common patterns and tools that can be used for this purpose.

About the Domain Model

The first thing you need to recognize is that your domain model is not really about data; it is about actions and questions such as “activate this user”, “deactivate this user”, “which users are currently activated?”, and “what is this user’s name?”. In classical terms: it’s about queries and commands.

Thinking in Commands

Let’s start by looking at the commands in your example: “activate this user” and “deactivate this user”. The nice thing about commands is that they can easily be expressed by small given-when-then scenario’s:

given an inactive user
when the admin activates this user
then the user becomes active
and a confirmation e-mail is sent to the user
and an entry is added to the system log
(etc. etc.)

Such scenario’s are useful to see how different parts of your infrastructure can be affected by a single command – in this case your database (some kind of ‘active’ flag), your mail server, your system log, etc.

Such scenario’s also really help you in setting up a Test Driven Development environment.

And finally, thinking in commands really helps you create a task-oriented application. Your users will appreciate this :-)

Expressing Commands

Django provides two easy ways of expressing commands; they are both valid options and it is not unusual to mix the two approaches.

The service layer

The service module has already been described by @Hedde. Here you define a separate module and each command is represented as a function.

services.py

def activate_user(user_id):
    user = User.objects.get(pk=user_id)

    # set active flag
    user.active = True
    user.save()

    # mail user
    send_mail(...)

    # etc etc

Using forms

The other way is to use a Django Form for each command. I prefer this approach, because it combines multiple closely related aspects:

  • execution of the command (what does it do?)
  • validation of the command parameters (can it do this?)
  • presentation of the command (how can I do this?)

forms.py

class ActivateUserForm(forms.Form):

    user_id = IntegerField(widget = UsernameSelectWidget, verbose_name="Select a user to activate")
    # the username select widget is not a standard Django widget, I just made it up

    def clean_user_id(self):
        user_id = self.cleaned_data['user_id']
        if User.objects.get(pk=user_id).active:
            raise ValidationError("This user cannot be activated")
        # you can also check authorizations etc. 
        return user_id

    def execute(self):
        """
        This is not a standard method in the forms API; it is intended to replace the 
        'extract-data-from-form-in-view-and-do-stuff' pattern by a more testable pattern. 
        """
        user_id = self.cleaned_data['user_id']

        user = User.objects.get(pk=user_id)

        # set active flag
        user.active = True
        user.save()

        # mail user
        send_mail(...)

        # etc etc

Thinking in Queries

You example did not contain any queries, so I took the liberty of making up a few useful queries. I prefer to use the term “question”, but queries is the classical terminology. Interesting queries are: “What is the name of this user?”, “Can this user log in?”, “Show me a list of deactivated users”, and “What is the geographical distribution of deactivated users?”

Before embarking on answering these queries, you should always ask yourself two questions: is this a presentational query just for my templates, and/or a business logic query tied to executing my commands, and/or a reporting query.

Presentational queries are merely made to improve the user interface. The answers to business logic queries directly affect the execution of your commands. Reporting queries are merely for analytical purposes and have looser time constraints. These categories are not mutually exclusive.

The other question is: “do I have complete control over the answers?” For example, when querying the user’s name (in this context) we do not have any control over the outcome, because we rely on an external API.

Making Queries

The most basic query in Django is the use of the Manager object:

User.objects.filter(active=True)

Of course, this only works if the data is actually represented in your data model. This is not always the case. In those cases, you can consider the options below.

Custom tags and filters

The first alternative is useful for queries that are merely presentational: custom tags and template filters.

template.html

<h1>Welcome, {{ user|friendly_name }}</h1>

template_tags.py

@register.filter
def friendly_name(user):
    return remote_api.get_cached_name(user.id)

Query methods

If your query is not merely presentational, you could add queries to your services.py (if you are using that), or introduce a queries.py module:

queries.py

def inactive_users():
    return User.objects.filter(active=False)


def users_called_publysher():
    for user in User.objects.all():
        if remote_api.get_cached_name(user.id) == "publysher":
            yield user 

Proxy models

Proxy models are very useful in the context of business logic and reporting. You basically define an enhanced subset of your model. You can override a Manager’s base QuerySet by overriding the Manager.get_queryset() method.

models.py

class InactiveUserManager(models.Manager):
    def get_queryset(self):
        query_set = super(InactiveUserManager, self).get_queryset()
        return query_set.filter(active=False)

class InactiveUser(User):
    """
    >>> for user in InactiveUser.objects.all():
    …        assert user.active is False 
    """

    objects = InactiveUserManager()
    class Meta:
        proxy = True

Query models

For queries that are inherently complex, but are executed quite often, there is the possibility of query models. A query model is a form of denormalization where relevant data for a single query is stored in a separate model. The trick of course is to keep the denormalized model in sync with the primary model. Query models can only be used if changes are entirely under your control.

models.py

class InactiveUserDistribution(models.Model):
    country = CharField(max_length=200)
    inactive_user_count = IntegerField(default=0)

The first option is to update these models in your commands. This is very useful if these models are only changed by one or two commands.

forms.py

class ActivateUserForm(forms.Form):
    # see above

    def execute(self):
        # see above
        query_model = InactiveUserDistribution.objects.get_or_create(country=user.country)
        query_model.inactive_user_count -= 1
        query_model.save()

A better option would be to use custom signals. These signals are of course emitted by your commands. Signals have the advantage that you can keep multiple query models in sync with your original model. Furthermore, signal processing can be offloaded to background tasks, using Celery or similar frameworks.

signals.py

user_activated = Signal(providing_args = ['user'])
user_deactivated = Signal(providing_args = ['user'])

forms.py

class ActivateUserForm(forms.Form):
    # see above

    def execute(self):
        # see above
        user_activated.send_robust(sender=self, user=user)

models.py

class InactiveUserDistribution(models.Model):
    # see above

@receiver(user_activated)
def on_user_activated(sender, **kwargs):
        user = kwargs['user']
        query_model = InactiveUserDistribution.objects.get_or_create(country=user.country)
        query_model.inactive_user_count -= 1
        query_model.save()

Keeping it clean

When using this approach, it becomes ridiculously easy to determine if your code stays clean. Just follow these guidelines:

  • Does my model contain methods that do more than managing database state? You should extract a command.
  • Does my model contain properties that do not map to database fields? You should extract a query.
  • Does my model reference infrastructure that is not my database (such as mail)? You should extract a command.

The same goes for views (because views often suffer from the same problem).

  • Does my view actively manage database models? You should extract a command.

Some References

Django documentation: proxy models

Django documentation: signals

Architecture: Domain Driven Design


回答 1

我通常在视图和模型之间实现服务层。这就像您项目的API一样,并为您提供了一个很好的直升机视图,可以了解正在发生的事情。我从我的一位同事那里继承了这种做法,该同事在Java项目(JSF)中经常使用这种分层技术,例如:

models.py

class Book:
   author = models.ForeignKey(User)
   title = models.CharField(max_length=125)

   class Meta:
       app_label = "library"

services.py

from library.models import Book

def get_books(limit=None, **filters):
    """ simple service function for retrieving books can be widely extended """
    return Book.objects.filter(**filters)[:limit]  # list[:None] will return the entire list

views.py

from library.services import get_books

class BookListView(ListView):
    """ simple view, e.g. implement a _build and _apply filters function """
    queryset = get_books()

请注意,我通常将模型,视图和服务带到模块级别,并根据项目的规模进一步分开

I usually implement a service layer in between views and models. This acts like your project’s API and gives you a good helicopter view of what is going on. I inherited this practice from a colleague of mine that uses this layering technique a lot with Java projects (JSF), e.g:

models.py

class Book:
   author = models.ForeignKey(User)
   title = models.CharField(max_length=125)

   class Meta:
       app_label = "library"

services.py

from library.models import Book

def get_books(limit=None, **filters):
    """ simple service function for retrieving books can be widely extended """
    return Book.objects.filter(**filters)[:limit]  # list[:None] will return the entire list

views.py

from library.services import get_books

class BookListView(ListView):
    """ simple view, e.g. implement a _build and _apply filters function """
    queryset = get_books()

Mind you, I usually take models, views and services to module level and separate even further depending on the project’s size


回答 2

首先,不要重复自己

然后,请注意不要过度设计,有时这只是浪费时间,并使某人失去对重要内容的关注。回顾python禅宗不时。

看一下活跃的项目

  • 更多的人=更多需要适当组织
  • Django的存储库,他们有一个简单的结构。
  • 点子库,他们有一个straigtforward目录结构。
  • 面料库也是一个很好的来看待。

    • 您可以将所有模型放置在 yourapp/models/logicalgroup.py
  • 例如 UserGroup相关模型可能会失败yourapp/models/users.py
  • 例如 PollQuestionAnswer…可以去下yourapp/models/polls.py
  • 加载您需要的内容 __all__里面东西yourapp/models/__init__.py

有关MVC的更多信息

  • 模型就是你的数据
    • 这包括您的实际数据
    • 这还包括您的会话/ Cookie /缓存/ FS /索引数据
  • 用户与控制器交互以操纵模型
    • 这可以是API,也可以是保存/更新数据的视图
    • 可以通过request.GET/ 进行调整request.POST … etc
    • 也考虑分页过滤
  • 数据更新视图
    • 模板获取数据并相应地格式化
    • 甚至没有模板的API都是视图的一部分;例如tastypiepiston
    • 这也应该考虑中间件。

利用中间件 / 模板标签

  • 如果您需要为每个请求完成一些工作,那么中间件是一种解决方法。
    • 例如添加时间戳
    • 例如,更新有关网页点击量的指标
    • 例如,填充缓存
  • 如果您的代码片段总是在格式化对象时反复出现,那么模板标签就不错了。
    • 例如,活动选项卡/ URL面包屑

利用模型经理

  • 创建User可以进入UserManager(models.Manager)
  • 实例的血腥细节应该在上面models.Model
  • 有关的细节,queryset可以进去models.Manager
  • 您可能想一次创建一个对象User,因此您可能认为它应该存在于模型本身,但是在创建对象时,您可能并没有所有的细节:

例:

class UserManager(models.Manager):
   def create_user(self, username, ...):
      # plain create
   def create_superuser(self, username, ...):
      # may set is_superuser field.
   def activate(self, username):
      # may use save() and send_mail()
   def activate_in_bulk(self, queryset):
      # may use queryset.update() instead of save()
      # may use send_mass_mail() instead of send_mail()

尽可能使用表格

如果您有映射到模型的表单,则可以省去很多样板代码。的ModelForm documentation还不错。如果您有很多自定义功能,则最好将表单的代码与模型代码分开(或者为避免更高级的使用有时避免循环导入错误)。

尽可能使用管理命令

  • 例如 yourapp/management/commands/createsuperuser.py
  • 例如 yourapp/management/commands/activateinbulk.py

如果您有业务逻辑,可以将其分离出来

  • django.contrib.auth 使用后端,就像db有一个后端…等。
  • setting为您的业务逻辑添加一个(例如AUTHENTICATION_BACKENDS
  • 你可以用 django.contrib.auth.backends.RemoteUserBackend
  • 你可以用 yourapp.backends.remote_api.RemoteUserBackend
  • 你可以用 yourapp.backends.memcached.RemoteUserBackend
  • 将困难的业务逻辑委托给后端
  • 确保在输入/输出上设置期望值。
  • 更改业务逻辑就像更改设置一样简单:)

后端示例:

class User(db.Models):
    def get_present_name(self): 
        # property became not deterministic in terms of database
        # data is taken from another service by api
        return remote_api.request_user_name(self.uid) or 'Anonymous' 

可能成为:

class User(db.Models):
   def get_present_name(self):
      for backend in get_backends():
         try:
            return backend.get_present_name(self)
         except: # make pylint happy.
            pass
      return None

有关设计模式的更多信息

有关界面边界的更多信息

  • 您要使用的代码确实是模型的一部分吗?->yourapp.models
  • 代码是业务逻辑的一部分吗?->yourapp.vendor
  • 代码是通用工具/库的一部分吗?->yourapp.libs
  • 代码是业务逻辑库的一部分吗?-> yourapp.libs.vendoryourapp.vendor.libs
  • 这是一个很好的例子:您可以独立测试代码吗?
    • 对很好 :)
    • 不,您可能有接口问题
    • 当有明确的分离时,使用嘲笑可以使单元测试变得轻而易举
  • 分离符合逻辑吗?
    • 对很好 :)
    • 不,您可能无法单独测试这些逻辑概念。
  • 您认为当您获得10倍以上的代码时是否需要重构?
    • 是的,没有好处,没有布宜诺斯艾利斯,重构可能需要大量工作
    • 不,那太棒了!

简而言之,您可以

  • yourapp/core/backends.py
  • yourapp/core/models/__init__.py
  • yourapp/core/models/users.py
  • yourapp/core/models/questions.py
  • yourapp/core/backends.py
  • yourapp/core/forms.py
  • yourapp/core/handlers.py
  • yourapp/core/management/commands/__init__.py
  • yourapp/core/management/commands/closepolls.py
  • yourapp/core/management/commands/removeduplicates.py
  • yourapp/core/middleware.py
  • yourapp/core/signals.py
  • yourapp/core/templatetags/__init__.py
  • yourapp/core/templatetags/polls_extras.py
  • yourapp/core/views/__init__.py
  • yourapp/core/views/users.py
  • yourapp/core/views/questions.py
  • yourapp/core/signals.py
  • yourapp/lib/utils.py
  • yourapp/lib/textanalysis.py
  • yourapp/lib/ratings.py
  • yourapp/vendor/backends.py
  • yourapp/vendor/morebusinesslogic.py
  • yourapp/vendor/handlers.py
  • yourapp/vendor/middleware.py
  • yourapp/vendor/signals.py
  • yourapp/tests/test_polls.py
  • yourapp/tests/test_questions.py
  • yourapp/tests/test_duplicates.py
  • yourapp/tests/test_ratings.py

或任何其他可以帮助您的东西;找到所需的接口边界将对您有所帮助。

First of all, Don’t repeat yourself.

Then, please be careful not to overengineer, sometimes it is just a waste of time, and makes someone lose focus on what is important. Review the zen of python from time to time.

Take a look at active projects

  • more people = more need to organize properly
  • the django repository they have a straightforward structure.
  • the pip repository they have a straigtforward directory structure.
  • the fabric repository is also a good one to look at.

    • you can place all your models under yourapp/models/logicalgroup.py
  • e.g User, Group and related models can go under yourapp/models/users.py
  • e.g Poll, Question, Answer … could go under yourapp/models/polls.py
  • load what you need in __all__ inside of yourapp/models/__init__.py

More about MVC

  • model is your data
    • this includes your actual data
    • this also includes your session / cookie / cache / fs / index data
  • user interacts with controller to manipulate the model
    • this could be an API, or a view that saves/updates your data
    • this can be tuned with request.GET / request.POST …etc
    • think paging or filtering too.
  • the data updates the view
    • the templates take the data and format it accordingly
    • APIs even w/o templates are part of the view; e.g. tastypie or piston
    • this should also account for the middleware.

Take advantage of middleware / templatetags

  • If you need some work to be done for each request, middleware is one way to go.
    • e.g. adding timestamps
    • e.g. updating metrics about page hits
    • e.g. populating a cache
  • If you have snippets of code that always reoccur for formatting objects, templatetags are good.
    • e.g. active tab / url breadcrumbs

Take advantage of model managers

  • creating User can go in a UserManager(models.Manager).
  • gory details for instances should go on the models.Model.
  • gory details for queryset could go in a models.Manager.
  • you might want to create a User one at a time, so you may think that it should live on the model itself, but when creating the object, you probably don’t have all the details:

Example:

class UserManager(models.Manager):
   def create_user(self, username, ...):
      # plain create
   def create_superuser(self, username, ...):
      # may set is_superuser field.
   def activate(self, username):
      # may use save() and send_mail()
   def activate_in_bulk(self, queryset):
      # may use queryset.update() instead of save()
      # may use send_mass_mail() instead of send_mail()

Make use of forms where possible

A lot of boilerplate code can be eliminated if you have forms that map to a model. The ModelForm documentation is pretty good. Separating code for forms from model code can be good if you have a lot of customization (or sometimes avoid cyclic import errors for more advanced uses).

Use management commands when possible

  • e.g. yourapp/management/commands/createsuperuser.py
  • e.g. yourapp/management/commands/activateinbulk.py

if you have business logic, you can separate it out

  • django.contrib.auth uses backends, just like db has a backend…etc.
  • add a setting for your business logic (e.g. AUTHENTICATION_BACKENDS)
  • you could use django.contrib.auth.backends.RemoteUserBackend
  • you could use yourapp.backends.remote_api.RemoteUserBackend
  • you could use yourapp.backends.memcached.RemoteUserBackend
  • delegate the difficult business logic to the backend
  • make sure to set the expectation right on the input/output.
  • changing business logic is as simple as changing a setting :)

backend example:

class User(db.Models):
    def get_present_name(self): 
        # property became not deterministic in terms of database
        # data is taken from another service by api
        return remote_api.request_user_name(self.uid) or 'Anonymous' 

could become:

class User(db.Models):
   def get_present_name(self):
      for backend in get_backends():
         try:
            return backend.get_present_name(self)
         except: # make pylint happy.
            pass
      return None

more about design patterns

more about interface boundaries

  • Is the code you want to use really part of the models? -> yourapp.models
  • Is the code part of business logic? -> yourapp.vendor
  • Is the code part of generic tools / libs? -> yourapp.libs
  • Is the code part of business logic libs? -> yourapp.libs.vendor or yourapp.vendor.libs
  • Here is a good one: can you test your code independently?
    • yes, good :)
    • no, you may have an interface problem
    • when there is clear separation, unittest should be a breeze with the use of mocking
  • Is the separation logical?
    • yes, good :)
    • no, you may have trouble testing those logical concepts separately.
  • Do you think you will need to refactor when you get 10x more code?
    • yes, no good, no bueno, refactor could be a lot of work
    • no, that’s just awesome!

In short, you could have

  • yourapp/core/backends.py
  • yourapp/core/models/__init__.py
  • yourapp/core/models/users.py
  • yourapp/core/models/questions.py
  • yourapp/core/backends.py
  • yourapp/core/forms.py
  • yourapp/core/handlers.py
  • yourapp/core/management/commands/__init__.py
  • yourapp/core/management/commands/closepolls.py
  • yourapp/core/management/commands/removeduplicates.py
  • yourapp/core/middleware.py
  • yourapp/core/signals.py
  • yourapp/core/templatetags/__init__.py
  • yourapp/core/templatetags/polls_extras.py
  • yourapp/core/views/__init__.py
  • yourapp/core/views/users.py
  • yourapp/core/views/questions.py
  • yourapp/core/signals.py
  • yourapp/lib/utils.py
  • yourapp/lib/textanalysis.py
  • yourapp/lib/ratings.py
  • yourapp/vendor/backends.py
  • yourapp/vendor/morebusinesslogic.py
  • yourapp/vendor/handlers.py
  • yourapp/vendor/middleware.py
  • yourapp/vendor/signals.py
  • yourapp/tests/test_polls.py
  • yourapp/tests/test_questions.py
  • yourapp/tests/test_duplicates.py
  • yourapp/tests/test_ratings.py

or anything else that helps you; finding the interfaces you need and the boundaries will help you.


回答 3

Django使用了一种稍微修改的MVC。Django中没有“控制器”的概念。最接近的代理是“视图”,它倾向于与MVC转换混淆,因为在MVC中,视图更像Django的“模板”。

在Django中,“模型”不仅是数据库抽象。在某些方面,它与Django作为MVC的控制器的“视图”共同承担责任。它包含与实例相关联的全部行为。如果该实例需要与外部API交互作为其行为的一部分,那么那仍然是模型代码。实际上,根本不需要模型与数据库进行交互,因此可以想象,模型完全作为外部API的交互层存在。它是“模型”的更自由的概念。

Django employs a slightly modified kind of MVC. There’s no concept of a “controller” in Django. The closest proxy is a “view”, which tends to cause confusion with MVC converts because in MVC a view is more like Django’s “template”.

In Django, a “model” is not merely a database abstraction. In some respects, it shares duty with the Django’s “view” as the controller of MVC. It holds the entirety of behavior associated with an instance. If that instance needs to interact with an external API as part of it’s behavior, then that’s still model code. In fact, models aren’t required to interact with the database at all, so you could conceivable have models that entirely exist as an interactive layer to an external API. It’s a much more free concept of a “model”.


回答 4

正如Chris Pratt所说,在Django中,MVC结构不同于其他框架中使用的经典MVC模型,我认为这样做的主要原因是避免过于严格的应用程序结构,就像在其他MVC框架(如CakePHP)中那样。

在Django中,MVC是通过以下方式实现的:

视图层分为两部分。该视图仅应用于管理HTTP请求,它们将被调用并对其进行响应。视图与应用程序的其余部分(表单,模型表单,自定义类,在简单情况下直接与模型)进行通信。要创建界面,我们使用模板。模板就像Django的字符串一样,它将一个上下文映射到其中,并且该上下文由应用程序传达给视图(当视图询问时)。

模型层提供封装,抽象,验证,智能,并使您的数据面向对象(他们说有朝一日DBMS也将面向对象)。这并不意味着您应该制作巨大的models.py文件(实际上,一个很好的建议是将模型分成不同的文件,将它们放入名为“ models”的文件夹中,在其中创建一个“ __init__.py”文件导入所有模型并最终使用models.Model类的属性“ app_label”的文件夹)。模型应该使您摆脱对数据的操作,这将使您的应用程序更简单。如果需要,您还应该为模型创建外部类,例如“工具”。您还可以在模型中使用继承,将模型的Meta类的“抽象”属性设置为“真”。

其余在哪里?好吧,小型Web应用程序通常是数据的一种接口,在某些小型程序中,使用视图查询或插入数据就足够了。更常见的情况是使用Forms或ModelForms,它们实际上是“控制器”。这不是解决一个常见问题的实用方法,而且是非常快速的方法。这就是网站要做的事情。

如果Forms不适合您,那么您应该创建自己的类来解决问题,一个很好的例子是管理应用程序:您可以阅读ModelAmin代码,它实际上可以用作控制器。没有标准的结构,我建议您检查现有的Django应用程序,具体取决于每种情况。这就是Django开发人员的意图,您可以添加xml解析器类,API连接器类,添加Celery来执行任务,为基于反应堆的应用程序而扭曲,仅使用ORM,制作Web服务,修改管理应用程序等等。 ..您有责任制作高质量的代码,无论是否尊重MVC哲学,使其基于模块并创建自己的抽象层。非常灵活。

我的建议是:尽可能多地阅读代码,周围有很多django应用程序,但是不要那么认真地对待它们。每种情况都是不同的,模式和理论会有所帮助,但并非总是如此,这不是很精确,django只是为您提供了一些有用的工具,您可以使用这些工具来减轻一些麻烦(例如管理界面,Web表单验证,i18n,观察者模式实施,所有以及之前提到的内容和其他内容),但是好的设计来自经验丰富的设计师。

PS .:使用auth应用程序中的“ User”类(来自标准django),您可以创建用户个人资料,或者至少读取其代码,这对您的情况很有用。

In Django, MVC structure is as Chris Pratt said, different from classical MVC model used in other frameworks, I think the main reason for doing this is avoiding a too strict application structure, like happens in others MVC frameworks like CakePHP.

In Django, MVC was implemented in the following way:

View layer is splitted in two. The views should be used only to manage HTTP requests, they are called and respond to them. Views communicate with the rest of your application (forms, modelforms, custom classes, of in simple cases directly with models). To create the interface we use Templates. Templates are string-like to Django, it maps a context into them, and this context was communicated to the view by the application (when view asks).

Model layer gives encapsulation, abstraction, validation, intelligence and makes your data object-oriented (they say someday DBMS will also). This doesn’t means that you should make huge models.py files (in fact a very good advice is to split your models in different files, put them into a folder called ‘models’, make an ‘__init__.py’ file into this folder where you import all your models and finally use the attribute ‘app_label’ of models.Model class). Model should abstract you from operating with data, it will make your application simpler. You should also, if required, create external classes, like “tools” for your models.You can also use heritage in models, setting the ‘abstract’ attribute of your model’s Meta class to ‘True’.

Where is the rest? Well, small web applications generally are a sort of an interface to data, in some small program cases using views to query or insert data would be enough. More common cases will use Forms or ModelForms, which are actually “controllers”. This is not other than a practical solution to a common problem, and a very fast one. It’s what a website use to do.

If Forms are not enogh for you, then you should create your own classes to do the magic, a very good example of this is admin application: you can read ModelAmin code, this actually works as a controller. There is not a standard structure, I suggest you to examine existing Django apps, it depends on each case. This is what Django developers intended, you can add xml parser class, an API connector class, add Celery for performing tasks, twisted for a reactor-based application, use only the ORM, make a web service, modify the admin application and more… It’s your responsability to make good quality code, respect MVC philosophy or not, make it module based and creating your own abstraction layers. It’s very flexible.

My advice: read as much code as you can, there are lots of django applications around, but don’t take them so seriously. Each case is different, patterns and theory helps, but not always, this is an imprecise cience, django just provide you good tools that you can use to aliviate some pains (like admin interface, web form validation, i18n, observer pattern implementation, all the previously mentioned and others), but good designs come from experienced designers.

PS.: use ‘User’ class from auth application (from standard django), you can make for example user profiles, or at least read its code, it will be useful for your case.


回答 5

一个古老的问题,但是我还是想提供我的解决方案。基于接受,模型对象也需要一些其他功能,而将它们放置在models.py中很尴尬。可以根据个人喜好单独编写繁琐的业务逻辑,但是我至少喜欢该模型来完成与自身相关的所有事情。该解决方案还为那些喜欢将所有逻辑放在模型中的人提供支持。

因此,我设计了一种hack,使我可以将逻辑与模型定义分开,并且仍然可以从IDE中获得所有提示。

优点应该很明显,但这列出了我观察到的一些优点:

  • 数据库定义仅保留了这一点-没有附加逻辑“垃圾”
  • 与模型相关的逻辑都整齐地放在一个地方
  • 所有服务(表单,REST,视图)都具有单个逻辑访问点
  • 最棒的是:一旦意识到我的models.py变得过于混乱并且不必将逻辑分开,就不必重写任何代码。分离是平滑且迭代的:我可以一次执行一个函数,也可以一次执行整个类或整个model.py。

我一直在Python 3.4和更高版本以及Django 1.8和更高版本上使用它。

app / models.py

....
from app.logic.user import UserLogic

class User(models.Model, UserLogic):
    field1 = models.AnyField(....)
    ... field definitions ...

app / logic / user.py

if False:
    # This allows the IDE to know about the User model and its member fields
    from main.models import User

class UserLogic(object):
    def logic_function(self: 'User'):
        ... code with hinting working normally ...

我唯一不知道的是如何使我的IDE(在本例中为PyCharm)识别UserLogic实际上是用户模型。但是由于这显然是黑客,所以我很高兴接受总是为self参数指定类型的小小的麻烦。

An old question, but I’d like to offer my solution anyway. It’s based on acceptance that model objects too require some additional functionality while it’s awkward to place it within the models.py. Heavy business logic may be written separately depending on personal taste, but I at least like the model to do everything related to itself. This solution also supports those who like to have all the logic placed within models themselves.

As such, I devised a hack that allows me to separate logic from model definitions and still get all the hinting from my IDE.

The advantages should be obvious, but this lists a few that I have observed:

  • DB definitions remain just that – no logic “garbage” attached
  • Model-related logic is all placed neatly in one place
  • All the services (forms, REST, views) have a single access point to logic
  • Best of all: I did not have to rewrite any code once I realised that my models.py became too cluttered and had to separate the logic away. The separation is smooth and iterative: I could do a function at a time or entire class or the entire models.py.

I have been using this with Python 3.4 and greater and Django 1.8 and greater.

app/models.py

....
from app.logic.user import UserLogic

class User(models.Model, UserLogic):
    field1 = models.AnyField(....)
    ... field definitions ...

app/logic/user.py

if False:
    # This allows the IDE to know about the User model and its member fields
    from main.models import User

class UserLogic(object):
    def logic_function(self: 'User'):
        ... code with hinting working normally ...

The only thing I can’t figure out is how to make my IDE (PyCharm in this case) recognise that UserLogic is actually User model. But since this is obviously a hack, I’m quite happy to accept the little nuisance of always specifying type for self parameter.


回答 6

我必须同意你的看法。Django有很多可能性,但是最好的起点是回顾Django的设计理念

  1. 从模型属性调用API是不理想的,似乎在视图中执行这样的事情并可能创建一个服务层来保持干燥是更有意义的。如果对API的调用是非阻塞的,并且调用成本很高,则可以将请求发送给服务工作者(从队列中消耗资源的工作者)。

  2. 按照Django的设计理念,模型封装了“对象”的各个方面。因此,与该对象相关的所有业务逻辑都应存在于此:

包括所有相关领域逻辑

模型应遵循Martin Fowler的Active Record设计模式来封装“对象”的各个方面。

  1. 您描述的副作用是显而易见的,这里的逻辑可以更好地分解为Querysets和manager。这是一个例子:

    models.py

    import datetime
    
    from djongo import models
    from django.db.models.query import QuerySet
    from django.contrib import admin
    from django.db import transaction
    
    
    class MyUser(models.Model):
    
        present_name = models.TextField(null=False, blank=True)
        status = models.TextField(null=False, blank=True)
        last_active = models.DateTimeField(auto_now=True, editable=False)
    
        # As mentioned you could put this in a template tag to pull it
        # from cache there. Depending on how it is used, it could be
        # retrieved from within the admin view or from a custom view
        # if that is the only place you will use it.
        #def get_present_name(self):
        #    # property became non-deterministic in terms of database
        #    # data is taken from another service by api
        #    return remote_api.request_user_name(self.uid) or 'Anonymous'
    
        # Moved to admin as an action
        # def activate(self):
        #     # method now has a side effect (send message to user)
        #     self.status = 'activated'
        #     self.save()
        #     # send email via email service
        #     #send_mail('Your account is activated!', '…', [self.email])
    
        class Meta:
            ordering = ['-id']  # Needed for DRF pagination
    
        def __unicode__(self):
            return '{}'.format(self.pk)
    
    
    class MyUserRegistrationQuerySet(QuerySet):
    
        def for_inactive_users(self):
            new_date = datetime.datetime.now() - datetime.timedelta(days=3*365)  # 3 Years ago
            return self.filter(last_active__lte=new_date.year)
    
        def by_user_id(self, user_ids):
            return self.filter(id__in=user_ids)
    
    
    class MyUserRegistrationManager(models.Manager):
    
        def get_query_set(self):
            return MyUserRegistrationQuerySet(self.model, using=self._db)
    
        def with_no_activity(self):
            return self.get_query_set().for_inactive_users()

    管理员

    # Then in model admin
    
    class MyUserRegistrationAdmin(admin.ModelAdmin):
        actions = (
            'send_welcome_emails',
        )
    
        def send_activate_emails(self, request, queryset):
            rows_affected = 0
            for obj in queryset:
                with transaction.commit_on_success():
                    # send_email('welcome_email', request, obj) # send email via email service
                    obj.status = 'activated'
                    obj.save()
                    rows_affected += 1
    
            self.message_user(request, 'sent %d' % rows_affected)
    
    admin.site.register(MyUser, MyUserRegistrationAdmin)

I would have to agree with you. There are a lot of possibilities in django but best place to start is reviewing Django’s design philosophy.

  1. Calling an API from a model property would not be ideal, it seems like it would make more sense to do something like this in the view and possibly create a service layer to keep things dry. If the call to the API is non-blocking and the call is an expensive one, sending the request to a service worker (a worker that consumes from a queue) might make sense.

  2. As per Django’s design philosophy models encapsulate every aspect of an “object”. So all business logic related to that object should live there:

Include all relevant domain logic

Models should encapsulate every aspect of an “object,” following Martin Fowler’s Active Record design pattern.

  1. The side effects you describe are apparent, the logic here could be better broken down into Querysets and managers. Here is an example:

    models.py

    import datetime
    
    from djongo import models
    from django.db.models.query import QuerySet
    from django.contrib import admin
    from django.db import transaction
    
    
    class MyUser(models.Model):
    
        present_name = models.TextField(null=False, blank=True)
        status = models.TextField(null=False, blank=True)
        last_active = models.DateTimeField(auto_now=True, editable=False)
    
        # As mentioned you could put this in a template tag to pull it
        # from cache there. Depending on how it is used, it could be
        # retrieved from within the admin view or from a custom view
        # if that is the only place you will use it.
        #def get_present_name(self):
        #    # property became non-deterministic in terms of database
        #    # data is taken from another service by api
        #    return remote_api.request_user_name(self.uid) or 'Anonymous'
    
        # Moved to admin as an action
        # def activate(self):
        #     # method now has a side effect (send message to user)
        #     self.status = 'activated'
        #     self.save()
        #     # send email via email service
        #     #send_mail('Your account is activated!', '…', [self.email])
    
        class Meta:
            ordering = ['-id']  # Needed for DRF pagination
    
        def __unicode__(self):
            return '{}'.format(self.pk)
    
    
    class MyUserRegistrationQuerySet(QuerySet):
    
        def for_inactive_users(self):
            new_date = datetime.datetime.now() - datetime.timedelta(days=3*365)  # 3 Years ago
            return self.filter(last_active__lte=new_date.year)
    
        def by_user_id(self, user_ids):
            return self.filter(id__in=user_ids)
    
    
    class MyUserRegistrationManager(models.Manager):
    
        def get_query_set(self):
            return MyUserRegistrationQuerySet(self.model, using=self._db)
    
        def with_no_activity(self):
            return self.get_query_set().for_inactive_users()
    

    admin.py

    # Then in model admin
    
    class MyUserRegistrationAdmin(admin.ModelAdmin):
        actions = (
            'send_welcome_emails',
        )
    
        def send_activate_emails(self, request, queryset):
            rows_affected = 0
            for obj in queryset:
                with transaction.commit_on_success():
                    # send_email('welcome_email', request, obj) # send email via email service
                    obj.status = 'activated'
                    obj.save()
                    rows_affected += 1
    
            self.message_user(request, 'sent %d' % rows_affected)
    
    admin.site.register(MyUser, MyUserRegistrationAdmin)
    

回答 7

我大多同意选择的答案(https://stackoverflow.com/a/12857584/871392),但想在“进行查询”部分中添加选项。

可以为模型定义QuerySet类,以进行过滤器查询等。之后,您可以将此查询集类代理给模型的管理器,就像内置管理器和QuerySet类一样。

虽然,如果必须查询多个数据模型以获得一个域模型,对我来说,将其放在像以前建议的那样的单独模块中似乎更合理。

I’m mostly agree with chosen answer (https://stackoverflow.com/a/12857584/871392), but want to add option in Making Queries section.

One can define QuerySet classes for models for make filter queries and so on. After that you can proxy this queryset class for model’s manager, like build-in Manager and QuerySet classes do.

Although, if you had to query several data models to get one domain model, it seems more reasonable to me to put this in separate module like suggested before.


回答 8

关于优缺点的不同选择的最全面的文章:

  1. 想法1:胖模型
  2. 想法2:将业务逻辑放入视图/表单
  3. 理念3:服务
  4. 理念4:QuerySet / Manager
  5. 结论

资料来源:https : //sunscrapers.com/blog/where-to-put-business-logic-django/

Most comprehensive article on the different options with pros and cons:

  1. Idea #1: Fat Models
  2. Idea #2: Putting Business Logic in Views/Forms
  3. Idea #3: Services
  4. Idea #4: QuerySets/Managers
  5. Conclusion

Source: https://sunscrapers.com/blog/where-to-put-business-logic-django/


回答 9

Django设计用于轻松交付网页。如果您对此不满意,则应该使用其他解决方案。

我在模型上写根或通用操作(具有相同的接口),在模型控制器上写其他操作。如果需要其他模型的操作,请导入其控制器。

这种方法对我和应用程序的复杂性已经足够。

Hedde的回应是一个示例,展示了django和python本身的灵活性。

无论如何,这是一个非常有趣的问题!

Django is designed to be easely used to deliver web pages. If you are not confortable with this perhaps you should use another solution.

I’m writting the root or common operations on the model (to have the same interface) and the others on the controller of the model. If I need an operation from other model I import its controller.

This approach it’s enough for me and the complexity of my applications.

Hedde’s response is an example that shows the flexibility of django and python itself.

Very interesting question anyway!


没有名为pkg_resources的模块

问题:没有名为pkg_resources的模块

我正在将Django应用程序部署到开发服务器,并且在运行时遇到此错误pip install -r requirements.txt

Traceback (most recent call last):
  File "/var/www/mydir/virtualenvs/dev/bin/pip", line 5, in <module>
    from pkg_resources import load_entry_point
ImportError: No module named pkg_resources

pkg_resources似乎与一起分发setuptools。最初,我认为可能不会将它安装到virtualenv中的Python,所以我setuptools 2.6使用以下命令将了(与Python相同的版本)安装到virtualenv 中的Python站点软件包中:

sh setuptools-0.6c11-py2.6.egg --install-dir /var/www/mydir/virtualenvs/dev/lib/python2.6/site-packages

编辑:这只发生在virtualenv内部。如果我在virtualenv之外打开控制台,则pkg_resources存在,但仍然出现相同的错误。

关于为什么pkg_resources不在路上的任何想法?

I’m deploying a Django app to a dev server and am hitting this error when I run pip install -r requirements.txt:

Traceback (most recent call last):
  File "/var/www/mydir/virtualenvs/dev/bin/pip", line 5, in <module>
    from pkg_resources import load_entry_point
ImportError: No module named pkg_resources

pkg_resources appears to be distributed with setuptools. Initially I thought this might not be installed to the Python in the virtualenv, so I installed setuptools 2.6 (same version as Python) to the Python site-packages in the virtualenv with the following command:

sh setuptools-0.6c11-py2.6.egg --install-dir /var/www/mydir/virtualenvs/dev/lib/python2.6/site-packages

EDIT: This only happens inside the virtualenv. If I open a console outside the virtualenv then pkg_resources is present, but I am still getting the same error.

Any ideas as to why pkg_resources is not on the path?


回答 0

2018年7月更新

现在大多数人都应该使用pip install setuptools(可能与一起使用sudo)。

有些人可能需要(重新)安装python-setuptools通过他们的软件包管理的软件包(apt-get installyum install,等)。

此问题可能高度取决于您的操作系统和开发环境。如果上述方法不适用于您,请参见下面的旧式/其他答案。

说明

此错误消息是由缺少/损坏的Python setuptools软件包引起的。根据Matt M.的注释和setuptools问题#581,以下引用的引导脚本不再是推荐的安装方法。

如果仍然对任何人有帮助,引导脚本说明将保留在下面。

旧版答案

ImportError今天在尝试使用点子时遇到了同样的问题。不知何故,该setuptools软件包已在我的Python环境中删除。

要解决此问题,请运行以下安装脚本setuptools

wget https://bootstrap.pypa.io/ez_setup.py -O - | python

(或者,如果您尚未wget安装(例如OS X),请尝试

curl https://bootstrap.pypa.io/ez_setup.py | python

可能带有sudo前缀。)

如果您使用的任何版本distribute,或setuptools0.6以下的版本,则必须先将其卸载。*

有关更多详细信息,请参见安装说明


*如果您已经可以使用distribute,则将其升级到“兼容性包装器” setuptools可以更轻松地进行切换。但是,如果事情已经坏了,请不要尝试。

July 2018 Update

Most people should now use pip install setuptools (possibly with sudo).

Some may need to (re)install the python-setuptools package via their package manager (apt-get install, yum install, etc.).

This issue can be highly dependent on your OS and dev environment. See the legacy/other answers below if the above isn’t working for you.

Explanation

This error message is caused by a missing/broken Python setuptools package. Per Matt M.’s comment and setuptools issue #581, the bootstrap script referred to below is no longer the recommended installation method.

The bootstrap script instructions will remain below, in case it’s still helpful to anyone.

Legacy Answer

I encountered the same ImportError today while trying to use pip. Somehow the setuptools package had been deleted in my Python environment.

To fix the issue, run the setup script for setuptools:

wget https://bootstrap.pypa.io/ez_setup.py -O - | python

(or if you don’t have wget installed (e.g. OS X), try

curl https://bootstrap.pypa.io/ez_setup.py | python

possibly with sudo prepended.)

If you have any version of distribute, or any setuptools below 0.6, you will have to uninstall it first.*

See Installation Instructions for further details.


* If you already have a working distribute, upgrading it to the “compatibility wrapper” that switches you over to setuptools is easier. But if things are already broken, don’t try that.


回答 1

sudo apt-get install --reinstall python-pkg-resources

在Debian中为我修复了该问题。似乎卸载某些.deb软件包(在我的情况下为扭曲集)已破坏python用于查找软件包的路径

sudo apt-get install --reinstall python-pkg-resources

fixed it for me in Debian. Seems like uninstalling some .deb packages (twisted set in my case) has broken the path python uses to find packages


回答 2

尝试在Ubuntu 13.10上将rhodecode安装到virtualenv时,我已经看到此错误。对我来说,解决方案是运行

pip install --upgrade setuptools
pip install --upgrade distribute 

在运行easy_install rhodecode之前。

I have seen this error while trying to install rhodecode to a virtualenv on ubuntu 13.10. For me the solution was to run

pip install --upgrade setuptools
pip install --upgrade distribute 

before I run easy_install rhodecode.


回答 3

这也发生在我身上。我认为,在virtualenv使用setuptools的情况下,如果requirements.txt包含“ distribute”条目,则会出现此问题。Pip将尝试修补setuptools以便为分发腾出空间,但不幸的是,它将失败一半。

一种简单的解决方案是删除当前的virtualenv,然后使用–distribute参数创建一个新的virtualenv。

如果使用virtualenvwrapper的示例:

$ deactivate
$ rmvirtualenv yourenv
$ mkvirtualenv yourenv --distribute
$ workon yourenv
$ pip install -r requirements.txt

It also happened to me. I think the problem will happen if the requirements.txt contains a “distribute” entry while the virtualenv uses setuptools. Pip will try to patch setuptools to make room for distribute, but unfortunately it will fail half way.

The easy solution is delete your current virtualenv then make a new virtualenv with –distribute argument.

An example if using virtualenvwrapper:

$ deactivate
$ rmvirtualenv yourenv
$ mkvirtualenv yourenv --distribute
$ workon yourenv
$ pip install -r requirements.txt

回答 4

在CentOS 6中,安装软件包python-setuptools对其进行了修复。

yum install python-setuptools

In CentOS 6 installing the package python-setuptools fixed it.

yum install python-setuptools

回答 5

我之前有这个错误,评分最高的答案给我一个错误,试图下载ez_setup.py文件。我找到了另一个来源,因此您可以运行以下命令:

curl http://peak.telecommunity.com/dist/ez_setup.py | python

我发现还必须使用sudo它才能使其正常工作,因此您可能需要运行:

sudo curl http://peak.telecommunity.com/dist/ez_setup.py | sudo python

我还创建了另一个位置,可以从以下位置下载脚本:

https://gist.github.com/ajtrichards/42e73562a89edb1039f3

I had this error earlier and the highest rated answer gave me an error trying to download the ez_setup.py file. I found another source so you can run the command:

curl http://peak.telecommunity.com/dist/ez_setup.py | python

I found that I also had to use sudo to get it working, so you may need to run:

sudo curl http://peak.telecommunity.com/dist/ez_setup.py | sudo python

I’ve also created another location that the script can be downloaded from:

https://gist.github.com/ajtrichards/42e73562a89edb1039f3


回答 6

在尝试了以下几个答案之后,与一位同事联系,在Ubuntu 16.04上为我工作的是:

pip install --force-reinstall -U setuptools
pip install --force-reinstall -U pip

就我而言,只有枕头3.1.1的旧版本有问题(枕头4.x正常工作),现在已解决!

After trying several of these answers, then reaching out to a colleague, what worked for me on Ubuntu 16.04 was:

pip install --force-reinstall -U setuptools
pip install --force-reinstall -U pip

In my case, it was only an old version of pillow 3.1.1 that was having trouble (pillow 4.x worked fine), and that’s now resolved!


回答 7

需要更多的须藤。然后使用easy_install安装pip。作品。

sudo wget https://bootstrap.pypa.io/ez_setup.py -O - | sudo python
sudo easy_install pip

Needed a little bit more sudo. Then used easy_install to install pip. Works.

sudo wget https://bootstrap.pypa.io/ez_setup.py -O - | sudo python
sudo easy_install pip

回答 8

我通过执行以下操作修复了virtualenv的错误:

从复制了pkg_resources.py

/Library/Python/2.7/site-packages/setuptools

/Library/Python/2.7/site-packages/

这可能是一个便宜的解决方法,但对我有用。

如果不存在安装工具,则可以通过键入尝试安装系统站点软件包virtualenv --system-site-packages /DESTINATION DIRECTORY,将最后一部分更改为要安装到的目录。pkg_rousources.py将在lib / python2.7 / site-packages中的该目录下

I fixed the error with virtualenv by doing this:

Copied pkg_resources.py from

/Library/Python/2.7/site-packages/setuptools

to

/Library/Python/2.7/site-packages/

This may be a cheap workaround, but it worked for me.

.

If setup tools doesn’t exist, you can try installing system-site-packages by typing virtualenv --system-site-packages /DESTINATION DIRECTORY, changing the last part to be the directory you want to install to. pkg_rousources.py will be under that directory in lib/python2.7/site-packages


回答 9

对我来说,导致此错误是因为我有一个名为“ site”的子目录!我不知道这是否是pip错误,但我从以下内容开始:

/some/dir/requirements.txt / some / dir / site /

pip install -r requirements.txt无法正常工作,出现上述错误!

将子文件夹从“ site”重命名为“ src”解决了该问题!也许pip正在寻找“网站包装”?疯。

For me, this error was being caused because I had a subdirectory called “site”! I don’t know if this is a pip bug or not, but I started with:

/some/dir/requirements.txt /some/dir/site/

pip install -r requirements.txt wouldn’t work, giving me the above error!

renaming the subfolder from “site” to “src” fixed the problem! Maybe pip is looking for “site-packages”? Crazy.


回答 10

当我将我的virtualenv激活为不同于创建它的用户时,我遇到了这个问题。看来是权限问题。我在尝试@cwc的答案时发现了这一点,并在输出中看到了这一点:

Installing easy_install script to /path/env/bin
error: /path/env/bin/easy_install: Permission denied

切换回创建virtualenv的用户,然后运行原始pip install命令没有任何问题。希望这可以帮助!

I had this problem when I had activated my virtualenv as a different user than the one who created it. It seems to be a permission problem. I discovered this when I tried the answer by @cwc and saw this in the output:

Installing easy_install script to /path/env/bin
error: /path/env/bin/easy_install: Permission denied

Switching back to the user that created the virtualenv, then running the original pip install command went without problems. Hope this helps!


回答 11

我今天也有这个问题。我只在虚拟环境中遇到问题。

对我来说,解决方案是停用虚拟环境,删除后再使用pip卸载virtualenv并重新安装。之后,我为我的项目创建了一个新的虚拟环境,然后pip在虚拟环境中都能正常工作,就像在正常环境中一样。

I had this problem today as well. I only got the problem inside the virtual env.

The solution for me was deactivating the virtual env, deleting and then uninstalling virtualenv with pip and reinstalling it. After that I created a new virtual env for my project, then pip worked fine both inside the virtual environment as in the normal environment.


回答 12

看起来他们已经离开了bitbucket,现在在github(https://github.com/pypa/setuptools)上

运行的命令是:

wget https://bootstrap.pypa.io/ez_setup.py -O - | sudo python

Looks like they have moved away from bitbucket and are now on github (https://github.com/pypa/setuptools)

Command to run is:

wget https://bootstrap.pypa.io/ez_setup.py -O - | sudo python

回答 13

对我来说,原来是上的权限问题site-packages。由于这只是我的开发环境,因此我提出了权限,然后一切又重新开始了:

sudo chmod -R a+rwx /path/to/my/venv/lib/python2.7/site-packages/

For me, it turned out to be a permissions problem on site-packages. Since it’s only my dev environment, I raised the permissions and everything is working again:

sudo chmod -R a+rwx /path/to/my/venv/lib/python2.7/site-packages/

回答 14

如果通过conda安装的应用程序遇到此问题,则解决方案(如此错误报告中所述)仅是使用以下命令安装安装工具:

conda install setuptools

If you are encountering this issue with an application installed via conda, the solution (as stated in this bug report) is simply to install setup-tools with:

conda install setuptools

回答 15

在Windows上,使用python 3.7,这对我有用:

pip install --upgrade setuptools --user

--user 将软件包安装在您的主目录中,该目录不需要管理员权限。

On Windows, with python 3.7, this worked for me:

pip install --upgrade setuptools --user

--user installs packages in your home directory, which doesn’t require admin privileges.


回答 16

简单的解决方法是您可以使用conda升级setuptools或整个环境。(特别适用于Windows用户。)

conda upgrade -c anaconda setuptools

如果删除了setuptools,则需要再次安装setuptools。

conda install -c anaconda setuptools

如果所有方法均无效,则可以升级conda环境。但是我不建议您需要重新安装和卸载某些软件包,因为这样做会加剧这种情况。

the simple resoluition is that you can use conda to upgrade setuptools or entire enviroment. (Specially for windows user.)

conda upgrade -c anaconda setuptools

if the setuptools is removed, you need to install setuptools again.

conda install -c anaconda setuptools

if these all methodes doesn’t work, you can upgrade conda environement. But I do not recommend that you need to reinstall and uninstall some packages because after that it will exacerbate the situation.


回答 17

显然您缺少setuptools。某些virtualenv版本默认情况下使用分发而不是setuptools。--setuptools在创建virtualenv时使用该选项,或者VIRTUALENV_SETUPTOOLS=1在您的环境中设置。

Apparently you’re missing setuptools. Some virtualenv versions use distribute instead of setuptools by default. Use the --setuptools option when creating the virtualenv or set the VIRTUALENV_SETUPTOOLS=1 in your environment.


回答 18

就我而言,我最初安装了2个python版本,后来又删除了较旧的版本。因此,在创建虚拟环境时

virtualenv venv

指的是卸载的python

什么对我有用

python3 -m virtualenv venv

当您尝试使用点子时也是如此。

In my case, I had 2 python versions installed initially and later I had deleted the older one. So while creating the virtual environment

virtualenv venv

was referring to the uninstalled python

What worked for me

python3 -m virtualenv venv

Same is true when you are trying to use pip.


回答 19

当我尝试遵循本OSX指南时,遇到了这个答案。对我python get-pip有用的是,跑步后,我还必须easy_install pip。这解决了根本无法运行点子的问题。我确实安装了一堆旧的Macport东西。那可能有冲突。

I came across this answer when I was trying to follow this guide for OSX. What worked for me was, after running python get-pip, I had to ALSO easy_install pip. That fixed the issue of not being able to run pip at all. I did have a bunch of old macport stuff installed. That may have conflicted.


回答 20

在Windows上,我安装了从www.lfd.uci.edu/~gohlke/pythonlibs/下载的pip然后出现了这个问题。

所以我应该先安装setuptools(easy_install)。

On windows, I installed pip downloaded from www.lfd.uci.edu/~gohlke/pythonlibs/ then encontered this problem.

So I should have installed setuptools(easy_install) first.


回答 21

只需setuptools通过以下方式重新安装您的:

$ sudo wget https://pypi.python.org/packages/source/s/setuptools/setuptools-0.6c11.tar.gz#md5=7df2a529a074f613b509fb44feefefe74e
$ tar -zxvf setuptools-0.6c11.tar.gz
$ cd setuptools-0.6c11/
$ sudo python setup.py build
$ sudo python setup.py install
$ sudo pip install --upgrade setuptools

那么一切都会好起来的。

just reinstall your setuptools by :

$ sudo wget https://pypi.python.org/packages/source/s/setuptools/setuptools-0.6c11.tar.gz#md5=7df2a529a074f613b509fb44feefefe74e
$ tar -zxvf setuptools-0.6c11.tar.gz
$ cd setuptools-0.6c11/
$ sudo python setup.py build
$ sudo python setup.py install
$ sudo pip install --upgrade setuptools

then everything will be fine.


回答 22

我使用CentOS 6.7,而我的python刚刚从2.6.6升级到2.7.11,在尝试了许多不同的答案之后,终于有以下一个工作了:

sudo yum install python-devel

希望能帮助同样情况的人。

I use CentOS 6.7, and my python was just upgrade from 2.6.6 to 2.7.11, after tried so many different answer, finally the following one does the job:

sudo yum install python-devel

Hope help someone in the same situation.


回答 23

没有一个发布的答案对我有用,所以我重新安装了pip并成功了!

sudo apt-get install python-setuptools python-dev build-essential 

sudo easy_install pip 

pip install --upgrade setuptools

(参考:http//www.saltycrane.com/blog/2010/02/how-install-pip-ubuntu/

None of the posted answers worked for me, so I reinstalled pip and it worked!

sudo apt-get install python-setuptools python-dev build-essential 

sudo easy_install pip 

pip install --upgrade setuptools

(reference: http://www.saltycrane.com/blog/2010/02/how-install-pip-ubuntu/)


回答 24

更新我的Ubuntu版本后,我遇到了这个问题。它似乎已经遍历并删除了我所有虚拟环境中的设置工具。

为了解决这个问题,我将虚拟环境重新安装回了目标目录。这清理了缺少的设置工具,并使一切重新运行。

例如:

~/RepoDir/TestProject$ virtualenv TestEnvironmentDir

I ran into this problem after updating my Ubuntu build. It seems to have gone through and removed set up tools in all of my virtual environments.

To remedy this I reinstalled the virtual environment back into the target directory. This cleaned up missing setup tools and got things running again.

e.g.:

~/RepoDir/TestProject$ virtualenv TestEnvironmentDir

回答 25

对我来说,一个很好的解决方法是使用--no-download选项virtualenv(VIRTUALENV_NO_DOWNLOAD=1 tox用于tox。)

For me a good fix was to use --no-download option to virtualenv (VIRTUALENV_NO_DOWNLOAD=1 tox for tox.)


回答 26

在Opensuse 42.1上,以下内容解决了此问题:

zypper in python-Pygments

On Opensuse 42.1 the following fixed this issue:

zypper in python-Pygments

回答 27

ImportError:没有名为pkg_resources的模块:解决方法是使用下面的命令重新安装python pip。

步骤:1登录到root用户。

sudo su root

步骤:2卸载python-pip软件包(如果存在)。

apt-get purge -y python-pip

步骤:3使用wget命令下载文件(在中下载文件pwd

wget https://bootstrap.pypa.io/get-pip.py

步骤:4运行python文件。

python ./get-pip.py

步骤:5 Finalic exicute安装命令。

apt-get install python-pip

注意:用户必须是root用户。

ImportError: No module named pkg_resources: the solution is to reinstall python pip using the following Command are under.

Step: 1 Login in root user.

sudo su root

Step: 2 Uninstall python-pip package if existing.

apt-get purge -y python-pip

Step: 3 Download files using wget command(File download in pwd )

wget https://bootstrap.pypa.io/get-pip.py

Step: 4 Run python file.

python ./get-pip.py

Step: 5 Finaly exicute installation command.

apt-get install python-pip

Note: User must be root.


回答 28

我在Google App Engine环境中遇到了该错误。并pip install -t lib setuptools解决了问题。

I experienced that error in my Google App Engine environment. And pip install -t lib setuptools fixed the issue.


回答 29

如果您使用的是Python 3,则应使用pip3而不是pip。该命令看起来像$ pip3 install requirements.txt

If you are using Python 3, you should use pip3 instead of pip. The command looks like $ pip3 install requirements.txt


使用Django和Python创建JSON响应

问题:使用Django和Python创建JSON响应

我正在尝试将服务器端Ajax响应脚本转换为Django HttpResponse,但显然无法正常工作。

这是服务器端脚本:

/* RECEIVE VALUE */
$validateValue=$_POST['validateValue'];
$validateId=$_POST['validateId'];
$validateError=$_POST['validateError'];

/* RETURN VALUE */
$arrayToJs = array();
$arrayToJs[0] = $validateId;
$arrayToJs[1] = $validateError;

if($validateValue =="Testuser"){  // Validate??
    $arrayToJs[2] = "true";       // RETURN TRUE
    echo '{"jsonValidateReturn":'.json_encode($arrayToJs).'}';  // RETURN ARRAY WITH success
}
else{
    for($x=0;$x<1000000;$x++){
        if($x == 990000){
            $arrayToJs[2] = "false";
            echo '{"jsonValidateReturn":'.json_encode($arrayToJs).'}';   // RETURNS ARRAY WITH ERROR.
        }
    }
}

这是转换后的代码

def validate_user(request):
    if request.method == 'POST':
        vld_value = request.POST.get('validateValue')
        vld_id = request.POST.get('validateId')
        vld_error = request.POST.get('validateError')

        array_to_js = [vld_id, vld_error, False]

        if vld_value == "TestUser":
            array_to_js[2] = True
            x = simplejson.dumps(array_to_js)
            return HttpResponse(x)
        else:
            array_to_js[2] = False
            x = simplejson.dumps(array_to_js)
            error = 'Error'
            return render_to_response('index.html',{'error':error},context_instance=RequestContext(request))
    return render_to_response('index.html',context_instance=RequestContext(request))

我正在使用simplejson对Python列表进行编码(因此它将返回JSON数组)。我还不能解决问题。但是我认为我对“回声”做错了。

I’m trying to convert a server side Ajax response script into a Django HttpResponse, but apparently it’s not working.

This is the server-side script:

/* RECEIVE VALUE */
$validateValue=$_POST['validateValue'];
$validateId=$_POST['validateId'];
$validateError=$_POST['validateError'];

/* RETURN VALUE */
$arrayToJs = array();
$arrayToJs[0] = $validateId;
$arrayToJs[1] = $validateError;

if($validateValue =="Testuser"){  // Validate??
    $arrayToJs[2] = "true";       // RETURN TRUE
    echo '{"jsonValidateReturn":'.json_encode($arrayToJs).'}';  // RETURN ARRAY WITH success
}
else{
    for($x=0;$x<1000000;$x++){
        if($x == 990000){
            $arrayToJs[2] = "false";
            echo '{"jsonValidateReturn":'.json_encode($arrayToJs).'}';   // RETURNS ARRAY WITH ERROR.
        }
    }
}

And this is the converted code

def validate_user(request):
    if request.method == 'POST':
        vld_value = request.POST.get('validateValue')
        vld_id = request.POST.get('validateId')
        vld_error = request.POST.get('validateError')

        array_to_js = [vld_id, vld_error, False]

        if vld_value == "TestUser":
            array_to_js[2] = True
            x = simplejson.dumps(array_to_js)
            return HttpResponse(x)
        else:
            array_to_js[2] = False
            x = simplejson.dumps(array_to_js)
            error = 'Error'
            return render_to_response('index.html',{'error':error},context_instance=RequestContext(request))
    return render_to_response('index.html',context_instance=RequestContext(request))

I’m using simplejson to encode the Python list (so it will return a JSON array). I couldn’t figure out the problem yet. But I think that I did something wrong about the ‘echo’.


回答 0

我通常使用字典,而不是列表来返回JSON内容。

import json

from django.http import HttpResponse

response_data = {}
response_data['result'] = 'error'
response_data['message'] = 'Some error message'

在Django 1.7之前的版本中,您将像这样返回它:

return HttpResponse(json.dumps(response_data), content_type="application/json")

对于Django 1.7+,请JsonResponse按照以下SO答案所示使用:

from django.http import JsonResponse
return JsonResponse({'foo':'bar'})

I usually use a dictionary, not a list to return JSON content.

import json

from django.http import HttpResponse

response_data = {}
response_data['result'] = 'error'
response_data['message'] = 'Some error message'

Pre-Django 1.7 you’d return it like this:

return HttpResponse(json.dumps(response_data), content_type="application/json")

For Django 1.7+, use JsonResponse as shown in this SO answer like so :

from django.http import JsonResponse
return JsonResponse({'foo':'bar'})

回答 1

Django 1.7的新功能

您可以使用JsonResponse对象。

从文档:

from django.http import JsonResponse
return JsonResponse({'foo':'bar'})

New in django 1.7

you could use JsonResponse objects.

from the docs:

from django.http import JsonResponse
return JsonResponse({'foo':'bar'})

回答 2

我用这个,很好用。

from django.utils import simplejson
from django.http import HttpResponse

def some_view(request):
    to_json = {
        "key1": "value1",
        "key2": "value2"
    }
    return HttpResponse(simplejson.dumps(to_json), mimetype='application/json')

选择:

from django.utils import simplejson

class JsonResponse(HttpResponse):
    """
        JSON response
    """
    def __init__(self, content, mimetype='application/json', status=None, content_type=None):
        super(JsonResponse, self).__init__(
            content=simplejson.dumps(content),
            mimetype=mimetype,
            status=status,
            content_type=content_type,
        )

在Django 1.7中,JsonResponse对象已添加到Django框架本身,这使此任务更加容易:

from django.http import JsonResponse
def some_view(request):
    return JsonResponse({"key": "value"})

I use this, it works fine.

from django.utils import simplejson
from django.http import HttpResponse

def some_view(request):
    to_json = {
        "key1": "value1",
        "key2": "value2"
    }
    return HttpResponse(simplejson.dumps(to_json), mimetype='application/json')

Alternative:

from django.utils import simplejson

class JsonResponse(HttpResponse):
    """
        JSON response
    """
    def __init__(self, content, mimetype='application/json', status=None, content_type=None):
        super(JsonResponse, self).__init__(
            content=simplejson.dumps(content),
            mimetype=mimetype,
            status=status,
            content_type=content_type,
        )

In Django 1.7 JsonResponse objects have been added to the Django framework itself which makes this task even easier:

from django.http import JsonResponse
def some_view(request):
    return JsonResponse({"key": "value"})

回答 3

从Django 1.7开始,您便拥有了所需的标准JsonResponse

from django.http import JsonResponse
...
return JsonResponse(array_to_js, safe=False)

您甚至不需要json.dump您的数组。

Since Django 1.7 you have a standard JsonResponse that’s exactly what you need:

from django.http import JsonResponse
...
return JsonResponse(array_to_js, safe=False)

You don’t even need to json.dump your array.


回答 4

from django.http import HttpResponse
import json

class JsonResponse(HttpResponse):
    def __init__(self, content={}, mimetype=None, status=None,
             content_type='application/json'):
        super(JsonResponse, self).__init__(json.dumps(content), mimetype=mimetype,
                                           status=status, content_type=content_type)

并在视图中:

resp_data = {'my_key': 'my value',}
return JsonResponse(resp_data)
from django.http import HttpResponse
import json

class JsonResponse(HttpResponse):
    def __init__(self, content={}, mimetype=None, status=None,
             content_type='application/json'):
        super(JsonResponse, self).__init__(json.dumps(content), mimetype=mimetype,
                                           status=status, content_type=content_type)

And in the view:

resp_data = {'my_key': 'my value',}
return JsonResponse(resp_data)

回答 5

对于使用Django 1.7+的用户

from django.http import JsonResponse

def your_view(request):
    json_object = {'key': "value"}
    return JsonResponse(json_object)

官方文档

For those who use Django 1.7+

from django.http import JsonResponse

def your_view(request):
    json_object = {'key': "value"}
    return JsonResponse(json_object)

official docs


回答 6

您将要使用django序列化程序来帮助处理unicode内容:

from django.core import serializers

json_serializer = serializers.get_serializer("json")()
    response =  json_serializer.serialize(list, ensure_ascii=False, indent=2, use_natural_keys=True)
    return HttpResponse(response, mimetype="application/json")

You’ll want to use the django serializer to help with unicode stuff:

from django.core import serializers

json_serializer = serializers.get_serializer("json")()
    response =  json_serializer.serialize(list, ensure_ascii=False, indent=2, use_natural_keys=True)
    return HttpResponse(response, mimetype="application/json")

回答 7

使用基于Django类的视图,您可以编写:

from django.views import View
from django.http import JsonResponse

class JsonView(View):
    def get(self, request):
        return JsonResponse({'some': 'data'})

并使用Django-Rest-Framework可以编写:

from rest_framework.views import APIView
from rest_framework.response import Response

class JsonView(APIView):
    def get(self, request):
        return Response({'some': 'data'})

With Django Class-based views you can write:

from django.views import View
from django.http import JsonResponse

class JsonView(View):
    def get(self, request):
        return JsonResponse({'some': 'data'})

and with Django-Rest-Framework you can write:

from rest_framework.views import APIView
from rest_framework.response import Response

class JsonView(APIView):
    def get(self, request):
        return Response({'some': 'data'})

回答 8

对于Django 1.7或更高版本,使用JsonResponse类非常方便,因为它是HttpResponse的子类。

from django.http import JsonResponse
    def profile(request):
        data = {
            'name': 'Raghav',
            'location': 'India',
            'is_active': False,
            'count': 28
        }
        return JsonResponse(data)

对于旧版本的Django,您必须使用HttpResponse对象。

import json
from django.http import HttpResponse

def profile(request):
    data = {
        'name': 'Raghav',
        'location': 'India',
        'is_active': False,
        'count': 28
    }
    dump = json.dumps(data)
    return HttpResponse(dump, content_type='application/json')

Its very convenient with Django version 1.7 or higher as you have the JsonResponse class, which is a subclass of HttpResponse.

from django.http import JsonResponse
    def profile(request):
        data = {
            'name': 'Raghav',
            'location': 'India',
            'is_active': False,
            'count': 28
        }
        return JsonResponse(data)

For older versions of Django, you must use an HttpResponse object.

import json
from django.http import HttpResponse

def profile(request):
    data = {
        'name': 'Raghav',
        'location': 'India',
        'is_active': False,
        'count': 28
    }
    dump = json.dumps(data)
    return HttpResponse(dump, content_type='application/json')

回答 9

如何在Ajax(json)中使用Google App Engine?

使用JQuery的代码Javascript:

$.ajax({
    url: '/ajax',
    dataType : 'json',
    cache: false,
    success: function(data) {
        alert('Load was performed.'+data.ajax_resp);
    }
});

程式码Python

class Ajax(webapp2.RequestHandler):
    def get(self):
        my_response = {'ajax_resp':'Hello, webapp World!'}
        datos = json.dumps(my_response)

        self.response.headers.add_header('content-type', 'application/json', charset='utf-8')
        self.response.out.write(datos)

How to use google app engine with ajax (json)?

Code Javascript with JQuery:

$.ajax({
    url: '/ajax',
    dataType : 'json',
    cache: false,
    success: function(data) {
        alert('Load was performed.'+data.ajax_resp);
    }
});

Code Python

class Ajax(webapp2.RequestHandler):
    def get(self):
        my_response = {'ajax_resp':'Hello, webapp World!'}
        datos = json.dumps(my_response)

        self.response.headers.add_header('content-type', 'application/json', charset='utf-8')
        self.response.out.write(datos)

回答 10

这是使用基于类的视图的首选版本。只需将基本View子类化并覆盖get()方法。

import json

class MyJsonView(View):

    def get(self, *args, **kwargs):
        resp = {'my_key': 'my value',}
        return HttpResponse(json.dumps(resp), mimetype="application/json" )

This is my preferred version using a class based view. Simply subclass the basic View and override the get()-method.

import json

class MyJsonView(View):

    def get(self, *args, **kwargs):
        resp = {'my_key': 'my value',}
        return HttpResponse(json.dumps(resp), mimetype="application/json" )

回答 11

Django代码views.py

def view(request):
    if request.method == 'POST':
        print request.body
        data = request.body
        return HttpResponse(json.dumps(data))

HTML代码view.html

<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
    $("#mySelect").change(function(){
        selected = $("#mySelect option:selected").text()
        $.ajax({
            type: 'POST',
            dataType: 'json',
            contentType: 'application/json; charset=utf-8',
            url: '/view/',
            data: {
                    'fruit': selected
                  },
            success: function(result) {
                        document.write(result)
                    }
    });
  });
});
</script>
</head>
<body>

<form>
    {{data}}
    <br>
Select your favorite fruit:
<select id="mySelect">
  <option value="apple" selected >Select fruit</option>
  <option value="apple">Apple</option>
  <option value="orange">Orange</option>
  <option value="pineapple">Pineapple</option>
  <option value="banana">Banana</option>
</select>
</form>
</body>
</html>

Django code views.py:

def view(request):
    if request.method == 'POST':
        print request.body
        data = request.body
        return HttpResponse(json.dumps(data))

HTML code view.html:

<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
    $("#mySelect").change(function(){
        selected = $("#mySelect option:selected").text()
        $.ajax({
            type: 'POST',
            dataType: 'json',
            contentType: 'application/json; charset=utf-8',
            url: '/view/',
            data: {
                    'fruit': selected
                  },
            success: function(result) {
                        document.write(result)
                    }
    });
  });
});
</script>
</head>
<body>

<form>
    {{data}}
    <br>
Select your favorite fruit:
<select id="mySelect">
  <option value="apple" selected >Select fruit</option>
  <option value="apple">Apple</option>
  <option value="orange">Orange</option>
  <option value="pineapple">Pineapple</option>
  <option value="banana">Banana</option>
</select>
</form>
</body>
</html>

回答 12

首先导入:

from django.http import HttpResponse

如果您已经有了JSON:

def your_method(request):
    your_json = [{'key1': value, 'key2': value}]
    return HttpResponse(your_json, 'application/json')

如果您从另一个HTTP请求获取JSON:

def your_method(request):
    response = request.get('https://www.example.com/get/json')
    return HttpResponse(response, 'application/json')

First import this:

from django.http import HttpResponse

If you have the JSON already:

def your_method(request):
    your_json = [{'key1': value, 'key2': value}]
    return HttpResponse(your_json, 'application/json')

If you get the JSON from another HTTP request:

def your_method(request):
    response = request.get('https://www.example.com/get/json')
    return HttpResponse(response, 'application/json')

回答 13

使用JsonResponse

from django.http import JsonResponse

Use JsonResponse

from django.http import JsonResponse

回答 14

在View中使用以下命令:

form.field.errors|striptags

用于获取没有html的验证消息

In View use this:

form.field.errors|striptags

for getting validation messages without html


没有名为MySQLdb的模块

问题:没有名为MySQLdb的模块

我正在使用Python 2.5.4版并安装MySQL 5.0版和Django。Django在Python上运行良好,但在MySQL上运行良好。我在Windows Vista中使用它。

I am using Python version 2.5.4 and install MySQL version 5.0 and Django. Django is working fine with Python, but not MySQL. I am using it in Windows Vista.


回答 0

您需要使用以下命令之一。哪一个取决于您拥有和使用的操作系统和软件。

  1. easy_install mysql-python(混合OS)
  2. pip安装mysql-python(mix os / python 2)
  3. pip安装mysqlclient(mix os / python 3)
  4. apt-get install python-mysqldb(Linux Ubuntu,…)
  5. cd / usr / ports / databases / py-MySQLdb &&使安装干净(FreeBSD)
  6. yum安装MySQL-python(Linux Fedora,CentOS …)

对于Windows,请参见以下答案:安装mysql-python(Windows)

You need to use one of the following commands. Which one depends on what OS and software you have and use.

  1. easy_install mysql-python (mix os)
  2. pip install mysql-python (mix os/ python 2)
  3. pip install mysqlclient (mix os/ python 3)
  4. apt-get install python-mysqldb (Linux Ubuntu, …)
  5. cd /usr/ports/databases/py-MySQLdb && make install clean (FreeBSD)
  6. yum install MySQL-python (Linux Fedora, CentOS …)

For Windows, see this answer: Install mysql-python (Windows)


回答 1

…并且记住没有针对python3.x的MySQLdb

(我知道问题是关于python2.x的,但是谷歌对这篇文章的评价很高)


编辑:如评论中所述,有一个MySQLdb的fork添加了Python 3支持:github.com/PyMySQL/mysqlclient-python

…and remember there is no MySQLdb for python3.x

(I know the question is about python2.x but google rates this post quite high)


EDIT: As stated in the comments, there’s a MySQLdb’s fork that adds Python 3 support: github.com/PyMySQL/mysqlclient-python


回答 2

如果您的python版本是3.5,请执行pip install mysqlclient,其他操作对我不起作用

if your python version is 3.5, do a pip install mysqlclient, other things didn’t work for me


回答 3

mysqldb是未预安装或未随Django一起安装的Python模块。您可以mysqldb 在此处下载。

mysqldb is a module for Python that doesn’t come pre-installed or with Django. You can download mysqldb here.


回答 4

Ubuntu:

sudo apt-get install python-mysqldb

Ubuntu:

sudo apt-get install python-mysqldb

回答 5

请注意,这并未针对python 3.x进行测试

在CMD中

pip install wheel
pip install pymysql

在settings.py中

import pymysql
pymysql.install_as_MySQLdb()

它和我一起工作

Note this is not tested for python 3.x

In CMD

pip install wheel
pip install pymysql

in settings.py

import pymysql
pymysql.install_as_MySQLdb()

It worked with me


回答 6

pip install PyMySQL

然后将这两行添加到您的Project / Project / init .py

import pymysql
pymysql.install_as_MySQLdb()

适用于WIN和python 3.3+

pip install PyMySQL

and then add this two lines to your Project/Project/init.py

import pymysql
pymysql.install_as_MySQLdb()

Works on WIN and python 3.3+


回答 7

尝试这个。

pip install MySQL-python

Try this.

pip install MySQL-python

回答 8

对于窗口:

pip install mysqlclient pymysql

然后:

导入pymysql pymysql.install_as_MySQLdb()

对于python 3 Ubuntu

sudo apt-get install -y python3-mysqldb

for window :

pip install mysqlclient pymysql

then:

import pymysql pymysql.install_as_MySQLdb()

for python 3 Ubuntu

sudo apt-get install -y python3-mysqldb

回答 9

如果pip install mysqlclient产生错误并且您使用Ubuntu,请尝试:

sudo apt-get install -y python-dev libmysqlclient-dev && sudo pip install mysqlclient

If pip install mysqlclient produces an error and you use Ubuntu, try:

sudo apt-get install -y python-dev libmysqlclient-dev && sudo pip install mysqlclient

回答 10

我在Windows下遇到了同样的情况,并寻找了解决方案。

看到这篇文章安装mysql-python(Windows)

它指出,安装这样的pip环境是困难的,需要许多其他依赖项。

但我最终知道,如果我们使用mysqlclient的版本降至1.3.4,则不再需要该要求,请尝试:

pip install mysqlclient==1.3.4

I met the same situation under windows, and searched for the solution.

Seeing this post Install mysql-python (Windows).

It points out installing such a pip environment is difficult, needs many other dependencies.

But I finally know that if we use mysqlclient with a version down to 1.3.4, it don’t need that requirements any more, so try:

pip install mysqlclient==1.3.4

回答 11

  • 使用转到您的项目目录cd
  • 源/ bin /激活(如果以前没有激活过,请激活环境)。
  • 运行命令 easy_install MySQL-python
  • Go to your project directory with cd.
  • source/bin/activate (activate your env. if not previously).
  • Run the command easy_install MySQL-python

回答 12

pip install --user mysqlclient 

上面的对我来说就像魅力一样对我有效。我实际上是从sqlalchemy出错。环境信息:

Python:3.6,Ubuntu:16.04,conda 4.6.8

pip install --user mysqlclient 

above works for me like charm for me.I go the error from sqlalchemy actually. Environment information :

Python : 3.6, Ubuntu : 16.04,conda 4.6.8


回答 13

感谢derevo,但我认为还有另一种好方法:

  1. 下载并安装ActivePython
  2. 打开命令提示符
  3. 类型 pypm install mysql-python
  4. 阅读特定于此软件包的注释。

我认为pypm它比easy_install

Thanks to derevo but I think there’s another good way for doing this:

  1. Download and install ActivePython
  2. Open Command Prompt
  3. Type pypm install mysql-python
  4. Read the notes specific to this package.

I think pypm is more powerful and reliable than easy_install.


回答 14

对于Python 3+版本

安装mysql-connector为:

pip3 install mysql-connector 

示例Python DB连接代码:

import mysql.connector
db_connection = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd=""
)
print(db_connection)

输出:

> <mysql.connector.connection.MySQLConnection object at > 0x000002338A4C6B00>

这意味着数据库已正确连接。

For Python 3+ version

install mysql-connector as:

pip3 install mysql-connector 

Sample Python DB connection code:

import mysql.connector
db_connection = mysql.connector.connect(
  host="localhost",
  user="root",
  passwd=""
)
print(db_connection)

Output:

> <mysql.connector.connection.MySQLConnection object at > 0x000002338A4C6B00>

This means, database is correctly connected.


回答 15

我个人建议使用pymysql而不是使用真正的MySQL连接器,该连接器为您提供独立于平台的界面,可以通过安装pip

您可以这样编辑SQLAlchemy URL模式: mysql+pymysql://username:passwd@host/database

I personally recommend using pymysql instead of using the genuine MySQL connector, which provides you with a platform independent interface and could be installed through pip.

And you could edit the SQLAlchemy URL schema like this: mysql+pymysql://username:passwd@host/database


回答 16

对于Python 3.6或更高版本sudo apt-get install libmysqlclient-dev,并pip3 install mysqlclient 不会把戏

For Python 3.6+ sudo apt-get install libmysqlclient-dev and pip3 install mysqlclient does the trick


回答 17

如果您在Vista上运行,则可能要签出Bitnami Django堆栈。它是由Apache,Python,MySQL等组成的一站式堆栈,与Bitrock跨平台安装程序打包在一起,使上手非常容易。它可以在Windows,Mac和Linux上运行。哦,是完全免费的:)

If you are running on Vista, you may want to check out the Bitnami Django stack. It is an all-in-one stack of Apache, Python, MySQL, etc. packaged with Bitrock crossplatform installers to make it really easy to get started. It runs on Windows, Mac and Linux. Oh, and is completely free :)


回答 18

我已经尝试了上面的方法,但是仍然没有名为“ MySQLdb”的模块,最后,我成功了

easy_install mysql-python

我的环境是unbuntu 14.04

I have tried methods above, but still no module named ‘MySQLdb’, finally, I succeed with

easy_install mysql-python

my env is unbuntu 14.04


回答 19

在OSX上,这些命令对我有用

brew install mysql-connector-c 
pip install MySQL-python

On OSX these commands worked for me

brew install mysql-connector-c 
pip install MySQL-python

回答 20

如果您使用的是SQLAlchemy,并且错误位于/site-packages/sqlalchemy/dialects/mysql/mysqldb.py

from ...connectors.mysqldb import (
                        MySQLDBExecutionContext,
                        MySQLDBCompiler,
                        MySQLDBIdentifierPreparer,
                        MySQLDBConnector
                    )

因此您可能错过了mysqldb连接器,SQLAlchemy解决方法是在安装mysql-python模块后重新安装sqlalchemy 。

If your are using SQLAlchemy and the error is in /site-packages/sqlalchemy/dialects/mysql/mysqldb.py:

from ...connectors.mysqldb import (
                        MySQLDBExecutionContext,
                        MySQLDBCompiler,
                        MySQLDBIdentifierPreparer,
                        MySQLDBConnector
                    )

so you may have missed mysqldb connector for SQLAlchemy and the solution is to re-install sqlalchemy after installing mysql-python module.


回答 21

Win10 / Python27对我有用:

easy_install mysql-python

所有其他“ pip install …”失败,并出现相关性错误

Win10 / Python27 this worked for me:

easy_install mysql-python

all other ‘pip install…’ failed with dependency errors


回答 22

以上都不是通过docker image在Ubuntu 18.04全新安装上为我工作的。

以下为我解决了它:

apt-get install holland python3-mysqldb

None of the above worked for me on an Ubuntu 18.04 fresh install via docker image.

The following solved it for me:

apt-get install holland python3-mysqldb


回答 23

在运行Catalina v10.15.2的Mac上,出现以下MySQLdb版本冲突:

ImportError: this is MySQLdb version (1, 2, 5, 'final', 1), but _mysql is version (1, 4, 6, 'final', 0)

为了解决这个问题,我做了以下工作:

pip uninstall MySQL-python
pip install MySQL-python

On my mac running Catalina v10.15.2, I had the following MySQLdb version conflict:

ImportError: this is MySQLdb version (1, 2, 5, 'final', 1), but _mysql is version (1, 4, 6, 'final', 0)

To resolve it, I did the following:

pip uninstall MySQL-python
pip install MySQL-python

回答 24

在Debian Buster上,以下解决方案适用于python 3.7:

sudo apt-get install libmysqlclient-dev
sudo apt-get install libssl-dev
pip install mysqlclient

On Debian Buster, the following solution worked for me with python 3.7:

sudo apt-get install libmysqlclient-dev
sudo apt-get install libssl-dev
pip install mysqlclient

回答 25

我在ubuntu(linux),对我有用的是

sudo apt-get install python3-dev default-libmysqlclient-dev build-essential

然后最后

pip install mysqlclient

I am at ubuntu (linux) and what worked for me was

sudo apt-get install python3-dev default-libmysqlclient-dev build-essential

and then finally

pip install mysqlclient

在Django中,“ related_name”是用来做什么的?

问题:在Django中,“ related_name”是用来做什么的?

related_name参数对on ManyToManyFieldForeignKeyfield有什么用?例如,给定以下代码,的作用是related_name='maps'什么?

class Map(db.Model):
    members = models.ManyToManyField(User, related_name='maps',
                                     verbose_name=_('members'))

What is the related_name argument useful for on ManyToManyField and ForeignKey fields? For example, given the following code, what is the effect of related_name='maps'?

class Map(db.Model):
    members = models.ManyToManyField(User, related_name='maps',
                                     verbose_name=_('members'))

回答 0

related_name属性指定从User模型回到模型的反向关系的名称。

如果不指定related_name,Django会自动使用带有后缀的型号的名称创建一个_set,例如User.map_set.all()

如果确实related_name=mapsUser模型上指定,User.map_set则仍然可以使用,但是User.maps.语法显然更简洁,更简洁。因此,例如,如果您有一个用户对象current_user,则可以current_user.maps.all()用来获取Map模型中与关联的所有实例current_user

Django文档有更多的细节。

The related_name attribute specifies the name of the reverse relation from the User model back to your model.

If you don’t specify a related_name, Django automatically creates one using the name of your model with the suffix _set, for instance User.map_set.all().

If you do specify, e.g. related_name=maps on the User model, User.map_set will still work, but the User.maps. syntax is obviously a bit cleaner and less clunky; so for example, if you had a user object current_user, you could use current_user.maps.all() to get all instances of your Map model that have a relation to current_user.

The Django documentation has more details.


回答 1

要添加到现有答案中-如果模型中有2个FK指向同一张表,则必须使用相关名称。例如物料清单

@with_author 
class BOM(models.Model): 
    name = models.CharField(max_length=200,null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    tomaterial =  models.ForeignKey(Material, related_name = 'tomaterial')
    frommaterial =  models.ForeignKey(Material, related_name = 'frommaterial')
    creation_time = models.DateTimeField(auto_now_add=True, blank=True)
    quantity = models.DecimalField(max_digits=19, decimal_places=10)

因此,当您必须访问此数据时,您只能使用相关名称

 bom = material.tomaterial.all().order_by('-creation_time')

否则它将无法正常工作(至少在同一张表中有2个FK的情况下,我无法跳过相关名称的使用。)

To add to existing answer – related name is a must in case there 2 FKs in the model that point to the same table. For example in case of Bill of material

@with_author 
class BOM(models.Model): 
    name = models.CharField(max_length=200,null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    tomaterial =  models.ForeignKey(Material, related_name = 'tomaterial')
    frommaterial =  models.ForeignKey(Material, related_name = 'frommaterial')
    creation_time = models.DateTimeField(auto_now_add=True, blank=True)
    quantity = models.DecimalField(max_digits=19, decimal_places=10)

So when you will have to access this data you only can use related name

 bom = material.tomaterial.all().order_by('-creation_time')

It is not working otherwise (at least I was not able to skip the usage of related name in case of 2 FK’s to the same table.)


回答 2

related_name如果您具有更复杂的相关类名,则该参数也很有用。例如,如果您具有外键关系:

class UserMapDataFrame(models.Model):
    user = models.ForeignKey(User) 

为了UserMapDataFrame从related中访问对象User,默认调用为User.usermapdataframe_set.all(),这很难阅读。

使用,related_name您可以指定一个更简单或更清晰的名称来获取反向关系。在这种情况下,如果您指定user = models.ForeignKey(User, related_name='map_data'),则呼叫将为User.map_data.all()

The related_name argument is also useful if you have more complex related class names. For example, if you have a foreign key relationship:

class UserMapDataFrame(models.Model):
    user = models.ForeignKey(User) 

In order to access UserMapDataFrame objects from the related User, the default call would be User.usermapdataframe_set.all(), which it is quite difficult to read.

Using the related_name allows you to specify a simpler or more legible name to get the reverse relation. In this case, if you specify user = models.ForeignKey(User, related_name='map_data'), the call would then be User.map_data.all().


回答 3

相关的名称参数实际上是一个选项。如果我们不设置它,Django会自动为我们创建关系的另一面。对于Map模型,Django将创建一个map_set属性,从而允许m.map_set在您的示例中访问(m是您的类实例)。Django使用的公式是模型的名称,后跟字符串_set。因此,相关的name参数仅覆盖Django的默认值,而不提供新的行为。

The related name parameter is actually an option. If we do not set it, Django automatically creates the other side of the relation for us. In the case of the Map model, Django would have created a map_set attribute, allowing access via m.map_set in your example(m being your class instance). The formula Django uses is the name of the model followed by the string _set. The related name parameter thus simply overrides Django’s default rather than providing new behavior.


回答 4

prefetch_related用于预取多对多和多对一关系数据的数据。 select_related是从单个值关系中选择数据。这两个都用于从模型的关系中获取数据。例如,您构建一个模型以及一个与其他模型有关系的模型。当请求到来时,您还将查询他们的关系数据,并且Django具有很好的机制来从他们的关系中访问数据,例如book.author.name,当您迭代用于获取其关系数据的模型列表时,Django会为每个单个关系数据创建每个请求。为了克服这个问题,我们确实有 prefetchd_relatedselected_related

prefetch_related use for prefetch data for Many to many and many to one relationship data. select_related is to select data from a single value relationship. Both of these are used to fetch data from their relationships from a model. For example, you build a model and a model that has a relationship with other models. When a request comes you will also query for their relationship data and Django has very good mechanisms To access data from their relationship like book.author.name but when you iterate a list of models for fetching their relationship data Django create each request for every single relationship data. To overcome this we do have prefetchd_related and selected_related


在django中区分null = True,空白= True

问题:在django中区分null = True,空白= True

当我们在Django中添加数据库字段时,通常会这样写:

models.CharField(max_length=100, null=True, blank=True)

同样是与做ForeignKeyDecimalField等有什么根本区别在其

  1. null=True 只要
  2. blank=True 只要
  3. null=Trueblank=True

在相对于不同的(CharFieldForeignKeyManyToManyFieldDateTimeField)字段。使用1/2/3有哪些优点/缺点?

When we add a database field in django we generally write:

models.CharField(max_length=100, null=True, blank=True)

The same is done with ForeignKey, DecimalField etc. What is the basic difference in having

  1. null=True only
  2. blank=True only
  3. null=True, blank=True

in respect to different (CharField, ForeignKey, ManyToManyField, DateTimeField) fields. What are the advantages/disadvantages of using 1/2/3?


回答 0

null=True在数据库的列中设置NULL(与相对NOT NULL)。Django字段类型(例如DateTimeField或)的空白值ForeignKey将存储NULL在数据库中。

blank确定是否需要表单中的字段。这包括管理员和您的自定义表单。如果blank=True是,则不需要该字段,如果是,则False该字段不能为空。

两者的组合是如此频繁,因为通常如果您要允许表单中的字段为空白,则还需要数据库来允许NULL该字段的值。CharFields和TextFields 是一个exceptions,在Django中永远不会另存为NULL。空值作为空字符串('')存储在DB中。

一些例子:

models.DateTimeField(blank=True) # raises IntegrityError if blank

models.DateTimeField(null=True) # NULL allowed, but must be filled out in a form

显然,这两个选项在使用上没有逻辑意义(尽管null=True, blank=False如果您希望始终以表单形式要求字段,则可能会有用例,当通过诸如Shell之类的对象处理对象时,这是可选的。)

models.CharField(blank=True) # No problem, blank is stored as ''

models.CharField(null=True) # NULL allowed, but will never be set as NULL

CHARTEXT类型永远不会NULL被Django 保存,因此null=True没有必要。但是,您可以手动设置这些字段之一None以强制将其设置为NULL。如果您有可能需要这样做的情况,则仍应包括null=True

null=True sets NULL (versus NOT NULL) on the column in your DB. Blank values for Django field types such as DateTimeField or ForeignKey will be stored as NULL in the DB.

blank determines whether the field will be required in forms. This includes the admin and your custom forms. If blank=True then the field will not be required, whereas if it’s False the field cannot be blank.

The combo of the two is so frequent because typically if you’re going to allow a field to be blank in your form, you’re going to also need your database to allow NULL values for that field. The exception is CharFields and TextFields, which in Django are never saved as NULL. Blank values are stored in the DB as an empty string ('').

A few examples:

models.DateTimeField(blank=True) # raises IntegrityError if blank

models.DateTimeField(null=True) # NULL allowed, but must be filled out in a form

Obviously, Those two options don’t make logical sense to use (though there might be a use case for null=True, blank=False if you want a field to always be required in forms, optional when dealing with an object through something like the shell.)

models.CharField(blank=True) # No problem, blank is stored as ''

models.CharField(null=True) # NULL allowed, but will never be set as NULL

CHAR and TEXT types are never saved as NULL by Django, so null=True is unnecessary. However, you can manually set one of these fields to None to force set it as NULL. If you have a scenario where that might be necessary, you should still include null=True.


回答 1

这是Django 1.8 的ORM映射blanknull字段的方式

class Test(models.Model):
    charNull        = models.CharField(max_length=10, null=True)
    charBlank       = models.CharField(max_length=10, blank=True)
    charNullBlank   = models.CharField(max_length=10, null=True, blank=True)

    intNull         = models.IntegerField(null=True)
    intBlank        = models.IntegerField(blank=True)
    intNullBlank    = models.IntegerField(null=True, blank=True)

    dateNull        = models.DateTimeField(null=True)
    dateBlank       = models.DateTimeField(blank=True)
    dateNullBlank   = models.DateTimeField(null=True, blank=True)        

PostgreSQL 9.4创建的数据库字段是:

CREATE TABLE Test (
  id              serial                    NOT NULL,

  "charNull"      character varying(10),
  "charBlank"     character varying(10)     NOT NULL,
  "charNullBlank" character varying(10),

  "intNull"       integer,
  "intBlank"      integer                   NOT NULL,
  "intNullBlank"  integer,

  "dateNull"      timestamp with time zone,
  "dateBlank"     timestamp with time zone  NOT NULL,
  "dateNullBlank" timestamp with time zone,
  CONSTRAINT Test_pkey PRIMARY KEY (id)
)

MySQL 5.6创建的数据库字段是:

CREATE TABLE Test (
     `id`            INT(11)     NOT  NULL    AUTO_INCREMENT,

     `charNull`      VARCHAR(10) NULL DEFAULT NULL,
     `charBlank`     VARCHAR(10) NOT  NULL,
     `charNullBlank` VARCHAR(10) NULL DEFAULT NULL,

     `intNull`       INT(11)     NULL DEFAULT NULL,
     `intBlank`      INT(11)     NOT  NULL,
     `intNullBlank`  INT(11)     NULL DEFAULT NULL,

     `dateNull`      DATETIME    NULL DEFAULT NULL,
     `dateBlank`     DATETIME    NOT  NULL,
     `dateNullBlank` DATETIME    NULL DEFAULT NULL
)

This is how the ORM maps blank & null fields for Django 1.8

class Test(models.Model):
    charNull        = models.CharField(max_length=10, null=True)
    charBlank       = models.CharField(max_length=10, blank=True)
    charNullBlank   = models.CharField(max_length=10, null=True, blank=True)

    intNull         = models.IntegerField(null=True)
    intBlank        = models.IntegerField(blank=True)
    intNullBlank    = models.IntegerField(null=True, blank=True)

    dateNull        = models.DateTimeField(null=True)
    dateBlank       = models.DateTimeField(blank=True)
    dateNullBlank   = models.DateTimeField(null=True, blank=True)        

The database fields created for PostgreSQL 9.4 are :

CREATE TABLE Test (
  id              serial                    NOT NULL,

  "charNull"      character varying(10),
  "charBlank"     character varying(10)     NOT NULL,
  "charNullBlank" character varying(10),

  "intNull"       integer,
  "intBlank"      integer                   NOT NULL,
  "intNullBlank"  integer,

  "dateNull"      timestamp with time zone,
  "dateBlank"     timestamp with time zone  NOT NULL,
  "dateNullBlank" timestamp with time zone,
  CONSTRAINT Test_pkey PRIMARY KEY (id)
)

The database fields created for MySQL 5.6 are :

CREATE TABLE Test (
     `id`            INT(11)     NOT  NULL    AUTO_INCREMENT,

     `charNull`      VARCHAR(10) NULL DEFAULT NULL,
     `charBlank`     VARCHAR(10) NOT  NULL,
     `charNullBlank` VARCHAR(10) NULL DEFAULT NULL,

     `intNull`       INT(11)     NULL DEFAULT NULL,
     `intBlank`      INT(11)     NOT  NULL,
     `intNullBlank`  INT(11)     NULL DEFAULT NULL,

     `dateNull`      DATETIME    NULL DEFAULT NULL,
     `dateBlank`     DATETIME    NOT  NULL,
     `dateNullBlank` DATETIME    NULL DEFAULT NULL
)

回答 2

如Django模型字段参考中所述:链接

栏位选项

以下参数可用于所有字段类型。所有都是可选的。


null

Field.null

如果为True,则Django将NULL在数据库中存储空值。默认值为False

避免null在基于字符串的字段(例如CharField和)上使用, TextField因为空字符串值将始终存储为空字符串,而不是NULL。如果基于字符串的字段具有null=True,则表示它具有两个“无数据”的可能值:NULL和空字符串。在大多数情况下,为“无数据”设置两个可能的值是多余的。Django约定是使用空字符串,而不是 NULL

对于基于字符串的字段和基于非字符串的字段,blank=True如果您希望允许表单中的空值,还需要进行设置,因为该null参数仅影响数据库存储(请参阅参考资料blank)。

注意

使用Oracle数据库后端时,无论此属性如何,都将存储值NULL表示空字符串


blank

Field.blank

如果为True,则该字段允许为空白。默认值为False

请注意,这与有所不同nullnull与数据库完全相关,而blank与验证相关。如果字段包含blank=True,则表单验证将允许输入一个空值。如果字段包含blank=False,则将需要该字段。

As said in Django Model Field reference: Link

Field options

The following arguments are available to all field types. All are optional.


null

Field.null

If True, Django will store empty values as NULL in the database. Default is False.

Avoid using null on string-based fields such as CharField and TextField because empty string values will always be stored as empty strings, not as NULL. If a string-based field has null=True, that means it has two possible values for “no data”: NULL, and the empty string. In most cases, it’s redundant to have two possible values for “no data”; the Django convention is to use the empty string, not NULL.

For both string-based and non-string-based fields, you will also need to set blank=True if you wish to permit empty values in forms, as the null parameter only affects database storage (see blank).

Note

When using the Oracle database backend, the value NULL will be stored to denote the empty string regardless of this attribute


blank

Field.blank

If True, the field is allowed to be blank. Default is False.

Note that this is different than null. null is purely database-related, whereas blank is validation-related. If a field has blank=True, form validation will allow entry of an empty value. If a field has blank=False, the field will be required.


回答 3

理解Django模型字段定义中的选项至少有两个作用是至关重要的:定义数据库表,定义默认格式和验证模型形式。(我之所以说“默认值”,是因为可以始终通过提供自定义表单来覆盖这些值。)某些选项影响数据库,某些选项影响表单,而某些选项同时影响这两种形式。

关于nullblank,其他答案已经明确表明,前者影响数据库表定义,而后者影响模型验证。我认为,通过查看所有四种可能配置的用例,可以使区分更加清楚:

  • null=Falseblank=False:这是默认的配置和手段,该值在所有情况下需要。

  • null=Trueblank=True:表示该字段在所有情况下都是可选的。(但是,如下所述,这不是使基于字符串的字段为可选的推荐方法。)

  • null=Falseblank=True:表示表单不需要值,但是数据库需要。有许多用例:

    • 最常见的用法是用于基于字符串的可选字段。如文档中所述,Django习惯用法是使用空字符串表示缺少的值。如果NULL还允许,您将最终以两种不同的方式指示缺失值。

    • 另一种常见情况是,您想根据另一个字段的值自动计算一个字段(例如,使用您的save()方法)。您不希望用户以某种形式提供值(因此blank=True),但是您希望数据库强制始终提供值(null=False)。

    • 另一个用途是当您想要指示a ManyToManyField是可选的时。因为此字段是作为单独的表而不是数据库列实现的,null所以没有意义blank不过,的值仍会影响表单,控制在没有关系时验证是否成功。

  • null=Trueblank=False:表示表单需要一个值,但数据库不需要。这可能是最不常用的配置,但是有一些用例:

    • 要求用户始终包含一个值是完全合理的,即使您的业务逻辑实际上并不需要它也是如此。毕竟,表单只是添加和编辑数据的一种方式。您可能拥有的代码生成的数据不需要与人工编辑器一样严格的验证。

    • 我看到的另一个用例是当你有一个ForeignKey你不想允许级联删除的情况。也就是说,在正常使用中,该关系应始终存在(blank=False),但是如果它指向的对象恰好被删除,则您也不想删除该对象。在这种情况下,您可以使用null=Trueon_delete=models.SET_NULL实现一种简单的软删除

It’s crucial to understand that the options in a Django model field definition serve (at least) two purposes: defining the database tables, and defining the default format and validation of model forms. (I say “default” because the values can always be overridden by providing a custom form.) Some options affect the database, some options affect forms, and some affect both.

When it comes to null and blank, other answers have already made clear that the former affects the database table definition and the latter affects model validation. I think the distinction can be made even clearer by looking at use cases for all four possible configurations:

  • null=False, blank=False: This is the default configuration and means that the value is required in all circumstances.

  • null=True, blank=True: This means that the field is optional in all circumstances. (As noted below, though, this is not the recommended way to make string-based fields optional.)

  • null=False, blank=True: This means that the form doesn’t require a value but the database does. There are a number of use cases for this:

    • The most common use is for optional string-based fields. As noted in the documentation, the Django idiom is to use the empty string to indicate a missing value. If NULL was also allowed you would end up with two different ways to indicate a missing value.

    • Another common situation is that you want to calculate one field automatically based on the value of another (in your save() method, say). You don’t want the user to provide the value in a form (hence blank=True), but you do want the database to enforce that a value is always provided (null=False).

    • Another use is when you want to indicate that a ManyToManyField is optional. Because this field is implemented as a separate table rather than a database column, null is meaningless. The value of blank will still affect forms, though, controlling whether or not validation will succeed when there are no relations.

  • null=True, blank=False: This means that the form requires a value but the database doesn’t. This may be the most infrequently used configuration, but there are some use cases for it:

    • It’s perfectly reasonable to require your users to always include a value even if it’s not actually required by your business logic. After all, forms are only one way of adding and editing data. You may have code that is generating data which doesn’t need the same stringent validation that you want to require of a human editor.

    • Another use case that I’ve seen is when you have a ForeignKey for which you don’t wish to allow cascade deletion. That is, in normal use the relation should always be there (blank=False), but if the thing it points to happens to be deleted, you don’t want this object to be deleted too. In that case you can use null=True and on_delete=models.SET_NULL to implement a simple kind of soft deletion.


回答 4

您可能有答案,但是直到今天,仍然很难判断是否将null = True或blank = True或两者都放在一个字段中。我个人认为为开发人员提供这么多的选择是非常无用的,而且令人困惑。让句柄根据需要为空或空格。

我遵循这张表,来自Django的两个独家新闻在此处输入图片说明

该表显示了何时对每种字段类型使用null或空白

You may have your answer however till this day it’s difficult to judge whether to put null=True or blank=True or both to a field. I personally think it’s pretty useless and confusing to provide so many options to developers. Let the handle the nulls or blanks however they want.

I follow this table, from Two Scoops of Django: enter image description here

Table showing when to use null or blank for each field type


回答 5

简单null=True定义数据库应该接受NULL值,另一方面,blank=True在表单验证中定义此字段是否应该接受空白值(如果blank=True它接受该字段中没有值的表单,并且blank=False在表单验证中为[默认值],它将显示此字段为必填错误。

null=True/False 与数据库有关

blank=True/False 与表单验证有关

Simply null=True defines database should accept NULL values, on other hand blank=True defines on form validation this field should accept blank values or not(If blank=True it accept form without a value in that field and blank=False[default value] on form validation it will show This field is required error.

null=True/False related to database

blank=True/False related to form validation


回答 6

这是带有blank= True和的字段的示例null=True

description = models.TextField(blank = True,null = True)

在这种情况下:: blank = True告诉我们的表格可以将描述字段留空

null = True:告诉我们的数据库可以在db字段中记录一个空值并且不给出错误。

Here is an example of the field with blank= True and null=True

description = models.TextField(blank=True, null= True)

In this case: blank = True: tells our form that it is ok to leave the description field blank

and

null = True: tells our database that it is ok to record a null value in our db field and not give an error.


回答 7

这里,是的主要区别null=Trueblank=True

两者的默认值nullblank值为False。这两个值都在字段级别起作用,即我们是否要保留字段nullblank

null=True将字段的值设置为NULL即无数据。它基本上是针对数据库列的值。

date = models.DateTimeField(null=True)

blank=True确定是否需要表单中的字段。这包括管理员和您自己的自定义表单。

title = models.CharField(blank=True) // title can be kept blank. 在数据库("")中将被存储。 null=True blank=True这意味着该字段在所有情况下都是可选的。

epic = models.ForeignKey(null=True, blank=True)
// The exception is CharFields() and TextFields(), which in Django are never saved as NULL. Blank values a

Here, is the main difference of null=True and blank=True:

The default value of both null and blank is False. Both of these values work at field level i.e., whether we want to keep a field null or blank.

null=True will set the field’s value to NULL i.e., no data. It is basically for the databases column value.

date = models.DateTimeField(null=True)

blank=True determines whether the field will be required in forms. This includes the admin and your own custom forms.

title = models.CharField(blank=True) // title can be kept blank. In the database ("") will be stored. null=True blank=True This means that the field is optional in all circumstances.

epic = models.ForeignKey(null=True, blank=True)
// The exception is CharFields() and TextFields(), which in Django are never saved as NULL. Blank values a

回答 8

null = True

意味着对于要填充的字段没有数据库的约束,因此您可以拥有一个具有空值的对象,该对象具有此选项。

blank = True

意味着没有django形式的验证约束。因此,当您modelForm为此模型填写时,可以不填写此选项。

null = True

Means there is no constraint of database for the field to be filled, so you can have an object with null value for the filled that has this option.

blank = True

Means there is no constraint of validation in django forms. so when you fill a modelForm for this model you can leave field with this option unfilled.


回答 9

null和blank的默认值为False。

空:与数据库有关。定义给定的数据库列是否将接受空值。

空白:与验证相关。调用form.is_valid()时,将在表单验证期间使用它。

话虽这么说,具有null = True和blank = False的字段是完全可以的。在数据库级别上,该字段可以为NULL,但是在应用程序级别上,它是必填字段。

现在,大多数开发人员都将其弄错了:为基于字符串的字段(如CharField和TextField)定义null = True。避免这样做。否则,您最终将获得两个可能的“无数据”值,即:和空字符串。为“无数据”设置两个可能的值是多余的。Django约定是使用空字符串,而不是NULL。

The default values of null and blank are False.

Null: It is database-related. Defines if a given database column will accept null values or not.

Blank: It is validation-related. It will be used during forms validation, when calling form.is_valid().

That being said, it is perfectly fine to have a field with null=True and blank=False. Meaning on the database level the field can be NULL, but in the application level it is a required field.

Now, where most developers get it wrong: Defining null=True for string-based fields such as CharField and TextField. Avoid doing that. Otherwise, you will end up having two possible values for “no data”, that is: None and an empty string. Having two possible values for “no data” is redundant. The Django convention is to use the empty string, not NULL.


回答 10

当我们在Django admin中保存任何内容时,将在Django级别和数据库级别进行两步验证。我们无法在数字字段中保存文本。

数据库的数据类型为NULL,没什么。当Django在数据库中创建列时,它指定它们不能为空。而且,如果您尝试保存NULL,则会出现数据库错误。

同样在Django-Admin级别,默认情况下所有字段都是必填字段,您无法保存空白字段,Django会抛出错误。

因此,如果要保存空白字段,则需要在Django和数据库级别允许它。blank = True-将允许管理面板中的空字段null = True-将允许将NULL保存到数据库列。

When we save anything in Django admin two steps validation happens, on Django level and on Database level. We can’t save text in a number field.

Database has data type NULL, it’s nothing. When Django creates columns in the database it specifies that they can’t be empty. And if you will try to save NULL you will get the database error.

Also on Django-Admin level, all fields are required by default, you can’t save blank field, Django will throw you an error.

So, if you want to save blank field you need to allow it on Django and Database level. blank=True – will allow empty field in admin panel null=True – will allow saving NULL to the database column.


回答 11

有一点null=True甚至在CharField或上也有必要TextField,那就是数据库unique为列设置了标志。

换句话说,如果您在Django中具有唯一的Char / TextField,则需要使用以下代码:

models.CharField(blank=True, null=True, unique=True)

对于非唯一的CharField或TextField,最好跳过null=True一些,否则某些字段将被设置为NULL,而另一些字段将被设置为“”,并且您每次都必须检查字段值是否为NULL。

There’s one point where null=True would be necessary even on a CharField or TextField and that is when the database has the unique flag set for the column.

In other words, if you’ve a unique Char/TextField in Django, you’ll need to use this:

models.CharField(blank=True, null=True, unique=True)

For non-unique CharField or TextField, you’ll be better off skipping the null=True otherwise some fields will get set as NULL while others as “” , and you’ll have to check the field value for NULL everytime.


回答 12

是数据库和空白是字段的验证要显示在文本框一样的用户界面得到的人的姓氏。如果lastname = models.charfield(blank = true),则没有要求用户输入姓氏,因为这是可选字段。如果lastname = models.charfield(null = true), 则意味着如果该字段未从用户那里获取任何值,则它将作为空字符串“”存储在数据库中。

null is for database and blank is for fields validation that you want to show on user interface like textfield to get the last name of person. If lastname=models.charfield (blank=true) it didnot ask user to enter last name as this is the optional field now. If lastname=models.charfield (null=true) then it means that if this field doesnot get any value from user then it will store in database as an empty string ” “.


回答 13

模型中null = True和blank = True的含义还取决于如何在表单类中定义这些字段。

假设您定义了以下类:

class Client (models.Model):
    name = models.CharField (max_length=100, blank=True)
    address = models.CharField (max_length=100, blank=False)

如果表单类的定义如下:

class ClientForm (ModelForm):
    class Meta:
        model = Client
        fields = ['name', 'address']
        widgets = {
            'name': forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
            'address': forms.TextInput (attrs = {'class': 'form-control form-control-sm'})
        }

然后,“名称”字段将不是强制性的(由于模型中的blank = True),而“地址”字段将是强制性的(由于模型中的blank = False)。

但是,如果已经这样定义ClientForm类:

class ClientForm (ModelForm):
    class Meta:
        model = Client
        fields = ['name', 'address']

    name = forms.CharField (
        widget = forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
    )
    address = forms.CharField (
        widget = forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
    )

然后,两个字段(“名称”和“地址”)都是必填字段“因为以声明方式定义的字段保持原样”https://docs.djangoproject.com/zh/3.0/topics/forms/modelforms/) ,即表单字段的’required’属性的默认值为True,即使在模型中将该字段设置为blank = True,这也将要求填写字段’name’和’address’。

The meaning of null=True and blank=True in the model also depends on how these fields were defined in the form class.

Suppose you have defined the following class:

class Client (models.Model):
    name = models.CharField (max_length=100, blank=True)
    address = models.CharField (max_length=100, blank=False)

If the form class has been defined like this:

class ClientForm (ModelForm):
    class Meta:
        model = Client
        fields = ['name', 'address']
        widgets = {
            'name': forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
            'address': forms.TextInput (attrs = {'class': 'form-control form-control-sm'})
        }

Then, the ‘name’ field will not be mandatory (due to the blank=True in the model) and the ‘address’ field will be mandatory (due to the blank=False in the model).

However, if the ClientForm class has been defined like this:

class ClientForm (ModelForm):
    class Meta:
        model = Client
        fields = ['name', 'address']

    name = forms.CharField (
        widget = forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
    )
    address = forms.CharField (
        widget = forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
    )

Then, both fields (‘name’ and ‘address’) will be mandatory, “since fields defined declaratively are left as-is” (https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/), i.e. the default for the ‘required’ attribute of the form field is True and this will require that the fields ‘name’ and ‘address’ are filled, even if, in the model, the field has been set to blank=True.


回答 14

null-如果为True,则默认为False,Django将在数据库中将null存储为null。

空白-如果为true,则默认值为False,该字段允许为空白

更多,请转到 https://docs.djangoproject.com/en/3.0/topics/db/models/

null – default is False if True, Django will store empty as null in the database.

blank – default is False if true that field is allowed to be blank

more, goto https://docs.djangoproject.com/en/3.0/topics/db/models/


回答 15

下表说明了主要区别:

+--------------------------------------------------------------------+
| Purpose                  | null=True        | blank = True         |
|--------------------------|------------------|----------------------|
| Field can be empty in DB | Do this          | Unaffected           |
|--------------------------|------------------|----------------------|
| ModelForm(required field)| Unaffected       | field not required   |
|--------------------------|------------------|----------------------|
| Form Validation          | Unaffected       | field not required   |
|--------------------------|------------------|----------------------|
| on_delete=SET_NULL       | Need this        | Unaffected           |
+--------------------------------------------------------------------+

This table below demonstrates the main differences:

+--------------------------------------------------------------------+
| Purpose                  | null=True        | blank = True         |
|--------------------------|------------------|----------------------|
| Field can be empty in DB | Do this          | Unaffected           |
|--------------------------|------------------|----------------------|
| ModelForm(required field)| Unaffected       | field not required   |
|--------------------------|------------------|----------------------|
| Form Validation          | Unaffected       | field not required   |
|--------------------------|------------------|----------------------|
| on_delete=SET_NULL       | Need this        | Unaffected           |
+--------------------------------------------------------------------+

回答 16

在很简单的话

空白不同于空值。

纯粹数据库相关的,而空白是验证相关的(在形式所需)

如果是null=True,Django会的store empty values as NULL in the database。如果有一个字段blank=True,则将进行表单验证allow entry of an empty value。如果字段的空白为False,则将需要该字段。

In Very simple words,

Blank is different than null.

null is purely database-related, whereas blank is validation-related(required in form).

If null=True, Django will store empty values as NULL in the database. If a field has blank=True, form validation will allow entry of an empty value. If a field has blank=False, the field will be required.


如何在Django queryset过滤中执行不等于?

问题:如何在Django queryset过滤中执行不等于?

在Django模型QuerySets中,我看到比较值存在__gt__lt,但是存在__ne// !=/ <>不等于?)。

我想使用不等于过滤掉:

例:

Model:
    bool a;
    int x;

我想要

results = Model.objects.exclude(a=true, x!=5)

!=不正确的语法。我试过__ne<>

我最终使用:

results = Model.objects.exclude(a=true, x__lt=5).exclude(a=true, x__gt=5)

In Django model QuerySets, I see that there is a __gt and __lt for comparitive values, but is there a __ne/!=/<> (not equals?)

I want to filter out using a not equals:

Example:

Model:
    bool a;
    int x;

I want

results = Model.objects.exclude(a=true, x!=5)

The != is not correct syntax. I tried __ne, <>.

I ended up using:

results = Model.objects.exclude(a=true, x__lt=5).exclude(a=true, x__gt=5)

回答 0

也许Q对象可以解决这个问题。我从未使用过它们,但似乎可以将它们取反并组合起来,就像普通的python表达式一样。

更新:我只是尝试了一下,它似乎工作得很好:

>>> from myapp.models import Entry
>>> from django.db.models import Q

>>> Entry.objects.filter(~Q(id = 3))

[<Entry: Entry object>, <Entry: Entry object>, <Entry: Entry object>, ...]

Maybe Q objects could be of help for this problem. I’ve never used them but it seems they can be negated and combined much like normal python expressions.

Update: I Just tried it out, it seems to work pretty well:

>>> from myapp.models import Entry
>>> from django.db.models import Q

>>> Entry.objects.filter(~Q(id = 3))

[<Entry: Entry object>, <Entry: Entry object>, <Entry: Entry object>, ...]

回答 1

您的查询似乎有一个双重否定,您想排除x不为5的所有行,换句话说,您想包括x为5的所有行。我相信这可以解决问题。

results = Model.objects.filter(x=5).exclude(a=true)

要回答您的特定问题,不存在“不等于”的问题,但这可能是因为django同时提供了“过滤器”和“排除”方法,因此您始终可以切换逻辑回合以获得所需的结果。

Your query appears to have a double negative, you want to exclude all rows where x is not 5, so in other words you want to include all rows where x IS 5. I believe this will do the trick.

results = Model.objects.filter(x=5).exclude(a=true)

To answer your specific question, there is no “not equal to” but that’s probably because django has both “filter” and “exclude” methods available so you can always just switch the logic round to get the desired result.


回答 2

field=value查询中的语法是的简写field__exact=value。也就是说,Django将查询运算符放在标识符中的查询字段上。Django支持以下运算符:

exact
iexact
contains
icontains
in
gt
gte
lt
lte
startswith
istartswith
endswith
iendswith
range
year
month
day
week_day
isnull
search
regex
iregex

我敢肯定,如Dave Vogt所建议的那样,将它们与Q对象结合使用,filter()或者exclude()Jason Baker所建议的那样使用,您将获得几乎所有可能查询所需的确切信息。

the field=value syntax in queries is a shorthand for field__exact=value. That is to say that Django puts query operators on query fields in the identifiers. Django supports the following operators:

exact
iexact
contains
icontains
in
gt
gte
lt
lte
startswith
istartswith
endswith
iendswith
range
year
month
day
week_day
isnull
search
regex
iregex

I’m sure by combining these with the Q objects as Dave Vogt suggests and using filter() or exclude() as Jason Baker suggests you’ll get exactly what you need for just about any possible query.


回答 3

使用Django 1.7创建自定义查找很容易。Django官方文档中有一个__ne查找示例。

您需要先创建查找本身:

from django.db.models import Lookup

class NotEqual(Lookup):
    lookup_name = 'ne'

    def as_sql(self, qn, connection):
        lhs, lhs_params = self.process_lhs(qn, connection)
        rhs, rhs_params = self.process_rhs(qn, connection)
        params = lhs_params + rhs_params
        return '%s <> %s' % (lhs, rhs), params

然后,您需要注册:

from django.db.models.fields import Field
Field.register_lookup(NotEqual)

现在,您可以__ne像下面这样在查询中使用查找:

results = Model.objects.exclude(a=True, x__ne=5)

It’s easy to create a custom lookup with Django 1.7. There’s an __ne lookup example in Django official documentation.

You need to create the lookup itself first:

from django.db.models import Lookup

class NotEqual(Lookup):
    lookup_name = 'ne'

    def as_sql(self, qn, connection):
        lhs, lhs_params = self.process_lhs(qn, connection)
        rhs, rhs_params = self.process_rhs(qn, connection)
        params = lhs_params + rhs_params
        return '%s <> %s' % (lhs, rhs), params

Then you need to register it:

from django.db.models.fields import Field
Field.register_lookup(NotEqual)

And now you can use the __ne lookup in your queries like this:

results = Model.objects.exclude(a=True, x__ne=5)

回答 4

Django 1.9 / 1.10中,有三个选项。

  1. excludefilter

    results = Model.objects.exclude(a=true).filter(x=5)
  2. 使用Q()对象~运算符

    from django.db.models import Q
    object_list = QuerySet.filter(~Q(a=True), x=5)
  3. 注册自定义查找功能

    from django.db.models import Lookup
    from django.db.models.fields import Field
    
    @Field.register_lookup
    class NotEqual(Lookup):
        lookup_name = 'ne'
    
        def as_sql(self, compiler, connection):
            lhs, lhs_params = self.process_lhs(compiler, connection)
            rhs, rhs_params = self.process_rhs(compiler, connection)
            params = lhs_params + rhs_params
            return '%s <> %s' % (lhs, rhs), params

    register_lookup在加装饰的Django 1.8和启用自定义查找和往常一样:

    results = Model.objects.exclude(a=True, x__ne=5)

In Django 1.9/1.10 there are three options.

  1. Chain exclude and filter

    results = Model.objects.exclude(a=true).filter(x=5)
    
  2. Use Q() objects and the ~ operator

    from django.db.models import Q
    object_list = QuerySet.filter(~Q(a=True), x=5)
    
  3. Register a custom lookup function

    from django.db.models import Lookup
    from django.db.models.fields import Field
    
    @Field.register_lookup
    class NotEqual(Lookup):
        lookup_name = 'ne'
    
        def as_sql(self, compiler, connection):
            lhs, lhs_params = self.process_lhs(compiler, connection)
            rhs, rhs_params = self.process_rhs(compiler, connection)
            params = lhs_params + rhs_params
            return '%s <> %s' % (lhs, rhs), params
    

    The register_lookup decorator was added in Django 1.8 and enables custom lookup as usual:

    results = Model.objects.exclude(a=True, x__ne=5)
    

回答 5

虽然与模型,您可以用过滤=__gt__gte__lt__lte,你不能使用ne!=或者<>。但是,使用Q对象可以实现更好的过滤。

您可以避免链接QuerySet.filter()QuerySet.exlude(),并使用以下代码:

from django.db.models import Q
object_list = QuerySet.filter(~Q(field='not wanted'), field='wanted')

While with the Models, you can filter with =, __gt, __gte, __lt, __lte, you cannot use ne, != or <>. However, you can achieve better filtering on using the Q object.

You can avoid chaining QuerySet.filter() and QuerySet.exlude(), and use this:

from django.db.models import Q
object_list = QuerySet.filter(~Q(field='not wanted'), field='wanted')

回答 6

等待设计决策。同时,使用exclude()

Django问题追踪器具有引人注目的条目#5763,标题为“ Queryset没有“不相等”的过滤运算符”。值得注意的是,(截至2016年4月)它是​​“在9年前开放”(在Django石器时代),“在4年前关闭”和“在5个月前最后一次更改”。

通读讨论,这很有趣。基本上,一些人认为__ne应增加也有人说exclude()是清晰的,因此__ne 应该添加。

(我同意前者,因为后者的论点大致相当于说Python不应该拥有!===,因为它已经拥有not了……)

Pending design decision. Meanwhile, use exclude()

The Django issue tracker has the remarkable entry #5763, titled “Queryset doesn’t have a “not equal” filter operator”. It is remarkable because (as of April 2016) it was “opened 9 years ago” (in the Django stone age), “closed 4 years ago”, and “last changed 5 months ago”.

Read through the discussion, it is interesting. Basically, some people argue __ne should be added while others say exclude() is clearer and hence __ne should not be added.

(I agree with the former, because the latter argument is roughly equivalent to saying Python should not have != because it has == and not already…)


回答 7

使用排除和过滤

results = Model.objects.filter(x=5).exclude(a=true)

Using exclude and filter

results = Model.objects.filter(x=5).exclude(a=true)

回答 8

您应该使用filterexclude喜欢这个

results = Model.objects.exclude(a=true).filter(x=5)

You should use filter and exclude like this

results = Model.objects.exclude(a=true).filter(x=5)

回答 9

代码的最后一位将排除x!= 5并且a为True的所有对象。尝试这个:

results = Model.objects.filter(a=False, x=5)

请记住,上一行中的=符号将False赋给参数a,并将数字5赋给参数x。它不是在检查是否相等。因此,实际上没有任何方法可以在查询调用中使用!=符号。

The last bit of code will exclude all objects where x!=5 and a is True. Try this:

results = Model.objects.filter(a=False, x=5)

Remember, the = sign in the above line is assigning False to the parameter a and the number 5 to the parameter x. It’s not checking for equality. Thus, there isn’t really any way to use the != symbol in a query call.


回答 10

结果= Model.objects.filter(a = True).exclude(x = 5)
生成此sql:
从tablex中选择*,其中a = 0且x!= 5
sql取决于您的True / False字段的表示方式以及数据库引擎。Django代码是您所需要的。

results = Model.objects.filter(a = True).exclude(x = 5)
Generetes this sql:
select * from tablex where a != 0 and x !=5
The sql depends on how your True/False field is represented, and the database engine. The django code is all you need though.

回答 11

Django-model-values(公开:作者)提供了NotEqual查找的实现,如此答案所示。它还为此提供了语法支持:

from model_values import F
Model.objects.exclude(F.x != 5, a=True)

Django-model-values (disclosure: author) provides an implementation of the NotEqual lookup, as in this answer. It also provides syntactic support for it:

from model_values import F
Model.objects.exclude(F.x != 5, a=True)

回答 12

您要查找的所有具有a=false 或的 对象x=5。在Django中,|充当查询集OR之间的运算符:

results = Model.objects.filter(a=false)|Model.objects.filter(x=5)

What you are looking for are all objects that have either a=false or x=5. In Django, | serves as OR operator between querysets:

results = Model.objects.filter(a=false)|Model.objects.filter(x=5)

回答 13

这将给您想要的结果。

from django.db.models import Q
results = Model.objects.exclude(Q(a=True) & ~Q(x=5))

对于不相等,可以~在相等查询上使用。显然,Q可以用来达到相等的查询。

This will give your desired result.

from django.db.models import Q
results = Model.objects.exclude(Q(a=True) & ~Q(x=5))

for not equal you can use ~ on an equal query. obviously, Q can be used to reach the equal query.


回答 14

注意此问题的许多错误答案!

Gerard的逻辑是正确的,尽管它将返回一个列表而不是一个查询集(这可能无关紧要)。

如果需要查询集,请使用Q:

from django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))

Watch out for lots of incorrect answers to this question!

Gerard’s logic is correct, though it will return a list rather than a queryset (which might not matter).

If you need a queryset, use Q:

from django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))

有Pytz时区列表吗?

问题:有Pytz时区列表吗?

我想知道Python库pytz中timezone参数的所有可能值是什么。怎么做?

for tz in pytz.all_timezones:
    print tz


Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
Africa/Bamako
Africa/Bangui
Africa/Banjul
Africa/Bissau
Africa/Blantyre
Africa/Brazzaville
Africa/Bujumbura
Africa/Cairo
Africa/Casablanca
Africa/Ceuta
Africa/Conakry
Africa/Dakar
Africa/Dar_es_Salaam
Africa/Djibouti
Africa/Douala
Africa/El_Aaiun
Africa/Freetown
Africa/Gaborone
Africa/Harare
Africa/Johannesburg
Africa/Juba
Africa/Kampala
Africa/Khartoum
Africa/Kigali
Africa/Kinshasa
Africa/Lagos
Africa/Libreville
Africa/Lome
Africa/Luanda
Africa/Lubumbashi
Africa/Lusaka
Africa/Malabo
Africa/Maputo
Africa/Maseru
Africa/Mbabane
Africa/Mogadishu
Africa/Monrovia
Africa/Nairobi
Africa/Ndjamena
Africa/Niamey
Africa/Nouakchott
Africa/Ouagadougou
Africa/Porto-Novo
Africa/Sao_Tome
Africa/Timbuktu
Africa/Tripoli
Africa/Tunis
Africa/Windhoek
America/Adak
America/Anchorage
America/Anguilla
America/Antigua
America/Araguaina
America/Argentina/Buenos_Aires
America/Argentina/Catamarca
America/Argentina/ComodRivadavia
America/Argentina/Cordoba
America/Argentina/Jujuy
America/Argentina/La_Rioja
America/Argentina/Mendoza
America/Argentina/Rio_Gallegos
America/Argentina/Salta
America/Argentina/San_Juan
America/Argentina/San_Luis
America/Argentina/Tucuman
America/Argentina/Ushuaia
America/Aruba
America/Asuncion
America/Atikokan
America/Atka
America/Bahia
America/Bahia_Banderas
America/Barbados
America/Belem
America/Belize
America/Blanc-Sablon
America/Boa_Vista
America/Bogota
America/Boise
America/Buenos_Aires
America/Cambridge_Bay
America/Campo_Grande
America/Cancun
America/Caracas
America/Catamarca
America/Cayenne
America/Cayman
America/Chicago
America/Chihuahua
America/Coral_Harbour
America/Cordoba
America/Costa_Rica
America/Creston
America/Cuiaba
America/Curacao
America/Danmarkshavn
America/Dawson
America/Dawson_Creek
America/Denver
America/Detroit
America/Dominica
America/Edmonton
America/Eirunepe
America/El_Salvador
America/Ensenada
America/Fort_Wayne
America/Fortaleza
America/Glace_Bay
America/Godthab
America/Goose_Bay
America/Grand_Turk
America/Grenada
America/Guadeloupe
America/Guatemala
America/Guayaquil
America/Guyana
America/Halifax
America/Havana
America/Hermosillo
America/Indiana/Indianapolis
America/Indiana/Knox
America/Indiana/Marengo
America/Indiana/Petersburg
America/Indiana/Tell_City
America/Indiana/Vevay
America/Indiana/Vincennes
America/Indiana/Winamac
America/Indianapolis
America/Inuvik
America/Iqaluit
America/Jamaica
America/Jujuy
America/Juneau
America/Kentucky/Louisville
America/Kentucky/Monticello
America/Knox_IN
America/Kralendijk
America/La_Paz
America/Lima
America/Los_Angeles
America/Louisville
America/Lower_Princes
America/Maceio
America/Managua
America/Manaus
America/Marigot
America/Martinique
America/Matamoros
America/Mazatlan
America/Mendoza
America/Menominee
America/Merida
America/Metlakatla
America/Mexico_City
America/Miquelon
America/Moncton
America/Monterrey
America/Montevideo
America/Montreal
America/Montserrat
America/Nassau
America/New_York
America/Nipigon
America/Nome
America/Noronha
America/North_Dakota/Beulah
America/North_Dakota/Center
America/North_Dakota/New_Salem
America/Ojinaga
America/Panama
America/Pangnirtung
America/Paramaribo
America/Phoenix
America/Port-au-Prince
America/Port_of_Spain
America/Porto_Acre
America/Porto_Velho
America/Puerto_Rico
America/Rainy_River
America/Rankin_Inlet
America/Recife
America/Regina
America/Resolute
America/Rio_Branco
America/Rosario
America/Santa_Isabel
America/Santarem
America/Santiago
America/Santo_Domingo
America/Sao_Paulo
America/Scoresbysund
America/Shiprock
America/Sitka
America/St_Barthelemy
America/St_Johns
America/St_Kitts
America/St_Lucia
America/St_Thomas
America/St_Vincent
America/Swift_Current
America/Tegucigalpa
America/Thule
America/Thunder_Bay
America/Tijuana
America/Toronto
America/Tortola
America/Vancouver
America/Virgin
America/Whitehorse
America/Winnipeg
America/Yakutat
America/Yellowknife
Antarctica/Casey
Antarctica/Davis
Antarctica/DumontDUrville
Antarctica/Macquarie
Antarctica/Mawson
Antarctica/McMurdo
Antarctica/Palmer
Antarctica/Rothera
Antarctica/South_Pole
Antarctica/Syowa
Antarctica/Vostok
Arctic/Longyearbyen
Asia/Aden
Asia/Almaty
Asia/Amman
Asia/Anadyr
Asia/Aqtau
Asia/Aqtobe
Asia/Ashgabat
Asia/Ashkhabad
Asia/Baghdad
Asia/Bahrain
Asia/Baku
Asia/Bangkok
Asia/Beirut
Asia/Bishkek
Asia/Brunei
Asia/Calcutta
Asia/Choibalsan
Asia/Chongqing
Asia/Chungking
Asia/Colombo
Asia/Dacca
Asia/Damascus
Asia/Dhaka
Asia/Dili
Asia/Dubai
Asia/Dushanbe
Asia/Gaza
Asia/Harbin
Asia/Hebron
Asia/Ho_Chi_Minh
Asia/Hong_Kong
Asia/Hovd
Asia/Irkutsk
Asia/Istanbul
Asia/Jakarta
Asia/Jayapura
Asia/Jerusalem
Asia/Kabul
Asia/Kamchatka
Asia/Karachi
Asia/Kashgar
Asia/Kathmandu
Asia/Katmandu
Asia/Kolkata
Asia/Krasnoyarsk
Asia/Kuala_Lumpur
Asia/Kuching
Asia/Kuwait
Asia/Macao
Asia/Macau
Asia/Magadan
Asia/Makassar
Asia/Manila
Asia/Muscat
Asia/Nicosia
Asia/Novokuznetsk
Asia/Novosibirsk
Asia/Omsk
Asia/Oral
Asia/Phnom_Penh
Asia/Pontianak
Asia/Pyongyang
Asia/Qatar
Asia/Qyzylorda
Asia/Rangoon
Asia/Riyadh
Asia/Saigon
Asia/Sakhalin
Asia/Samarkand
Asia/Seoul
Asia/Shanghai
Asia/Singapore
Asia/Taipei
Asia/Tashkent
Asia/Tbilisi
Asia/Tehran
Asia/Tel_Aviv
Asia/Thimbu
Asia/Thimphu
Asia/Tokyo
Asia/Ujung_Pandang
Asia/Ulaanbaatar
Asia/Ulan_Bator
Asia/Urumqi
Asia/Vientiane
Asia/Vladivostok
Asia/Yakutsk
Asia/Yekaterinburg
Asia/Yerevan
Atlantic/Azores
Atlantic/Bermuda
Atlantic/Canary
Atlantic/Cape_Verde
Atlantic/Faeroe
Atlantic/Faroe
Atlantic/Jan_Mayen
Atlantic/Madeira
Atlantic/Reykjavik
Atlantic/South_Georgia
Atlantic/St_Helena
Atlantic/Stanley
Australia/ACT
Australia/Adelaide
Australia/Brisbane
Australia/Broken_Hill
Australia/Canberra
Australia/Currie
Australia/Darwin
Australia/Eucla
Australia/Hobart
Australia/LHI
Australia/Lindeman
Australia/Lord_Howe
Australia/Melbourne
Australia/NSW
Australia/North
Australia/Perth
Australia/Queensland
Australia/South
Australia/Sydney
Australia/Tasmania
Australia/Victoria
Australia/West
Australia/Yancowinna
Brazil/Acre
Brazil/DeNoronha
Brazil/East
Brazil/West
CET
CST6CDT
Canada/Atlantic
Canada/Central
Canada/East-Saskatchewan
Canada/Eastern
Canada/Mountain
Canada/Newfoundland
Canada/Pacific
Canada/Saskatchewan
Canada/Yukon
Chile/Continental
Chile/EasterIsland
Cuba
EET
EST
EST5EDT
Egypt
Eire
Etc/GMT
Etc/GMT+0
Etc/GMT+1
Etc/GMT+10
Etc/GMT+11
Etc/GMT+12
Etc/GMT+2
Etc/GMT+3
Etc/GMT+4
Etc/GMT+5
Etc/GMT+6
Etc/GMT+7
Etc/GMT+8
Etc/GMT+9
Etc/GMT-0
Etc/GMT-1
Etc/GMT-10
Etc/GMT-11
Etc/GMT-12
Etc/GMT-13
Etc/GMT-14
Etc/GMT-2
Etc/GMT-3
Etc/GMT-4
Etc/GMT-5
Etc/GMT-6
Etc/GMT-7
Etc/GMT-8
Etc/GMT-9
Etc/GMT0
Etc/Greenwich
Etc/UCT
Etc/UTC
Etc/Universal
Etc/Zulu
Europe/Amsterdam
Europe/Andorra
Europe/Athens
Europe/Belfast
Europe/Belgrade
Europe/Berlin
Europe/Bratislava
Europe/Brussels
Europe/Bucharest
Europe/Budapest
Europe/Chisinau
Europe/Copenhagen
Europe/Dublin
Europe/Gibraltar
Europe/Guernsey
Europe/Helsinki
Europe/Isle_of_Man
Europe/Istanbul
Europe/Jersey
Europe/Kaliningrad
Europe/Kiev
Europe/Lisbon
Europe/Ljubljana
Europe/London
Europe/Luxembourg
Europe/Madrid
Europe/Malta
Europe/Mariehamn
Europe/Minsk
Europe/Monaco
Europe/Moscow
Europe/Nicosia
Europe/Oslo
Europe/Paris
Europe/Podgorica
Europe/Prague
Europe/Riga
Europe/Rome
Europe/Samara
Europe/San_Marino
Europe/Sarajevo
Europe/Simferopol
Europe/Skopje
Europe/Sofia
Europe/Stockholm
Europe/Tallinn
Europe/Tirane
Europe/Tiraspol
Europe/Uzhgorod
Europe/Vaduz
Europe/Vatican
Europe/Vienna
Europe/Vilnius
Europe/Volgograd
Europe/Warsaw
Europe/Zagreb
Europe/Zaporozhye
Europe/Zurich
GB
GB-Eire
GMT
GMT+0
GMT-0
GMT0
Greenwich
HST
Hongkong
Iceland
Indian/Antananarivo
Indian/Chagos
Indian/Christmas
Indian/Cocos
Indian/Comoro
Indian/Kerguelen
Indian/Mahe
Indian/Maldives
Indian/Mauritius
Indian/Mayotte
Indian/Reunion
Iran
Israel
Jamaica
Japan
Kwajalein
Libya
MET
MST
MST7MDT
Mexico/BajaNorte
Mexico/BajaSur
Mexico/General
NZ
NZ-CHAT
Navajo
PRC
PST8PDT
Pacific/Apia
Pacific/Auckland
Pacific/Chatham
Pacific/Chuuk
Pacific/Easter
Pacific/Efate
Pacific/Enderbury
Pacific/Fakaofo
Pacific/Fiji
Pacific/Funafuti
Pacific/Galapagos
Pacific/Gambier
Pacific/Guadalcanal
Pacific/Guam
Pacific/Honolulu
Pacific/Johnston
Pacific/Kiritimati
Pacific/Kosrae
Pacific/Kwajalein
Pacific/Majuro
Pacific/Marquesas
Pacific/Midway
Pacific/Nauru
Pacific/Niue
Pacific/Norfolk
Pacific/Noumea
Pacific/Pago_Pago
Pacific/Palau
Pacific/Pitcairn
Pacific/Pohnpei
Pacific/Ponape
Pacific/Port_Moresby
Pacific/Rarotonga
Pacific/Saipan
Pacific/Samoa
Pacific/Tahiti
Pacific/Tarawa
Pacific/Tongatapu
Pacific/Truk
Pacific/Wake
Pacific/Wallis
Pacific/Yap
Poland
Portugal
ROC
ROK
Singapore
Turkey
UCT
US/Alaska
US/Aleutian
US/Arizona
US/Central
US/East-Indiana
US/Eastern
US/Hawaii
US/Indiana-Starke
US/Michigan
US/Mountain
US/Pacific
US/Pacific-New
US/Samoa
UTC
Universal
W-SU
WET
Zulu

I would like to know what are all the possible values for the timezone argument in the Python library pytz. How to do it?

SOLUTION

for tz in pytz.all_timezones:
    print tz


Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
Africa/Bamako
Africa/Bangui
Africa/Banjul
Africa/Bissau
Africa/Blantyre
Africa/Brazzaville
Africa/Bujumbura
Africa/Cairo
Africa/Casablanca
Africa/Ceuta
Africa/Conakry
Africa/Dakar
Africa/Dar_es_Salaam
Africa/Djibouti
Africa/Douala
Africa/El_Aaiun
Africa/Freetown
Africa/Gaborone
Africa/Harare
Africa/Johannesburg
Africa/Juba
Africa/Kampala
Africa/Khartoum
Africa/Kigali
Africa/Kinshasa
Africa/Lagos
Africa/Libreville
Africa/Lome
Africa/Luanda
Africa/Lubumbashi
Africa/Lusaka
Africa/Malabo
Africa/Maputo
Africa/Maseru
Africa/Mbabane
Africa/Mogadishu
Africa/Monrovia
Africa/Nairobi
Africa/Ndjamena
Africa/Niamey
Africa/Nouakchott
Africa/Ouagadougou
Africa/Porto-Novo
Africa/Sao_Tome
Africa/Timbuktu
Africa/Tripoli
Africa/Tunis
Africa/Windhoek
America/Adak
America/Anchorage
America/Anguilla
America/Antigua
America/Araguaina
America/Argentina/Buenos_Aires
America/Argentina/Catamarca
America/Argentina/ComodRivadavia
America/Argentina/Cordoba
America/Argentina/Jujuy
America/Argentina/La_Rioja
America/Argentina/Mendoza
America/Argentina/Rio_Gallegos
America/Argentina/Salta
America/Argentina/San_Juan
America/Argentina/San_Luis
America/Argentina/Tucuman
America/Argentina/Ushuaia
America/Aruba
America/Asuncion
America/Atikokan
America/Atka
America/Bahia
America/Bahia_Banderas
America/Barbados
America/Belem
America/Belize
America/Blanc-Sablon
America/Boa_Vista
America/Bogota
America/Boise
America/Buenos_Aires
America/Cambridge_Bay
America/Campo_Grande
America/Cancun
America/Caracas
America/Catamarca
America/Cayenne
America/Cayman
America/Chicago
America/Chihuahua
America/Coral_Harbour
America/Cordoba
America/Costa_Rica
America/Creston
America/Cuiaba
America/Curacao
America/Danmarkshavn
America/Dawson
America/Dawson_Creek
America/Denver
America/Detroit
America/Dominica
America/Edmonton
America/Eirunepe
America/El_Salvador
America/Ensenada
America/Fort_Wayne
America/Fortaleza
America/Glace_Bay
America/Godthab
America/Goose_Bay
America/Grand_Turk
America/Grenada
America/Guadeloupe
America/Guatemala
America/Guayaquil
America/Guyana
America/Halifax
America/Havana
America/Hermosillo
America/Indiana/Indianapolis
America/Indiana/Knox
America/Indiana/Marengo
America/Indiana/Petersburg
America/Indiana/Tell_City
America/Indiana/Vevay
America/Indiana/Vincennes
America/Indiana/Winamac
America/Indianapolis
America/Inuvik
America/Iqaluit
America/Jamaica
America/Jujuy
America/Juneau
America/Kentucky/Louisville
America/Kentucky/Monticello
America/Knox_IN
America/Kralendijk
America/La_Paz
America/Lima
America/Los_Angeles
America/Louisville
America/Lower_Princes
America/Maceio
America/Managua
America/Manaus
America/Marigot
America/Martinique
America/Matamoros
America/Mazatlan
America/Mendoza
America/Menominee
America/Merida
America/Metlakatla
America/Mexico_City
America/Miquelon
America/Moncton
America/Monterrey
America/Montevideo
America/Montreal
America/Montserrat
America/Nassau
America/New_York
America/Nipigon
America/Nome
America/Noronha
America/North_Dakota/Beulah
America/North_Dakota/Center
America/North_Dakota/New_Salem
America/Ojinaga
America/Panama
America/Pangnirtung
America/Paramaribo
America/Phoenix
America/Port-au-Prince
America/Port_of_Spain
America/Porto_Acre
America/Porto_Velho
America/Puerto_Rico
America/Rainy_River
America/Rankin_Inlet
America/Recife
America/Regina
America/Resolute
America/Rio_Branco
America/Rosario
America/Santa_Isabel
America/Santarem
America/Santiago
America/Santo_Domingo
America/Sao_Paulo
America/Scoresbysund
America/Shiprock
America/Sitka
America/St_Barthelemy
America/St_Johns
America/St_Kitts
America/St_Lucia
America/St_Thomas
America/St_Vincent
America/Swift_Current
America/Tegucigalpa
America/Thule
America/Thunder_Bay
America/Tijuana
America/Toronto
America/Tortola
America/Vancouver
America/Virgin
America/Whitehorse
America/Winnipeg
America/Yakutat
America/Yellowknife
Antarctica/Casey
Antarctica/Davis
Antarctica/DumontDUrville
Antarctica/Macquarie
Antarctica/Mawson
Antarctica/McMurdo
Antarctica/Palmer
Antarctica/Rothera
Antarctica/South_Pole
Antarctica/Syowa
Antarctica/Vostok
Arctic/Longyearbyen
Asia/Aden
Asia/Almaty
Asia/Amman
Asia/Anadyr
Asia/Aqtau
Asia/Aqtobe
Asia/Ashgabat
Asia/Ashkhabad
Asia/Baghdad
Asia/Bahrain
Asia/Baku
Asia/Bangkok
Asia/Beirut
Asia/Bishkek
Asia/Brunei
Asia/Calcutta
Asia/Choibalsan
Asia/Chongqing
Asia/Chungking
Asia/Colombo
Asia/Dacca
Asia/Damascus
Asia/Dhaka
Asia/Dili
Asia/Dubai
Asia/Dushanbe
Asia/Gaza
Asia/Harbin
Asia/Hebron
Asia/Ho_Chi_Minh
Asia/Hong_Kong
Asia/Hovd
Asia/Irkutsk
Asia/Istanbul
Asia/Jakarta
Asia/Jayapura
Asia/Jerusalem
Asia/Kabul
Asia/Kamchatka
Asia/Karachi
Asia/Kashgar
Asia/Kathmandu
Asia/Katmandu
Asia/Kolkata
Asia/Krasnoyarsk
Asia/Kuala_Lumpur
Asia/Kuching
Asia/Kuwait
Asia/Macao
Asia/Macau
Asia/Magadan
Asia/Makassar
Asia/Manila
Asia/Muscat
Asia/Nicosia
Asia/Novokuznetsk
Asia/Novosibirsk
Asia/Omsk
Asia/Oral
Asia/Phnom_Penh
Asia/Pontianak
Asia/Pyongyang
Asia/Qatar
Asia/Qyzylorda
Asia/Rangoon
Asia/Riyadh
Asia/Saigon
Asia/Sakhalin
Asia/Samarkand
Asia/Seoul
Asia/Shanghai
Asia/Singapore
Asia/Taipei
Asia/Tashkent
Asia/Tbilisi
Asia/Tehran
Asia/Tel_Aviv
Asia/Thimbu
Asia/Thimphu
Asia/Tokyo
Asia/Ujung_Pandang
Asia/Ulaanbaatar
Asia/Ulan_Bator
Asia/Urumqi
Asia/Vientiane
Asia/Vladivostok
Asia/Yakutsk
Asia/Yekaterinburg
Asia/Yerevan
Atlantic/Azores
Atlantic/Bermuda
Atlantic/Canary
Atlantic/Cape_Verde
Atlantic/Faeroe
Atlantic/Faroe
Atlantic/Jan_Mayen
Atlantic/Madeira
Atlantic/Reykjavik
Atlantic/South_Georgia
Atlantic/St_Helena
Atlantic/Stanley
Australia/ACT
Australia/Adelaide
Australia/Brisbane
Australia/Broken_Hill
Australia/Canberra
Australia/Currie
Australia/Darwin
Australia/Eucla
Australia/Hobart
Australia/LHI
Australia/Lindeman
Australia/Lord_Howe
Australia/Melbourne
Australia/NSW
Australia/North
Australia/Perth
Australia/Queensland
Australia/South
Australia/Sydney
Australia/Tasmania
Australia/Victoria
Australia/West
Australia/Yancowinna
Brazil/Acre
Brazil/DeNoronha
Brazil/East
Brazil/West
CET
CST6CDT
Canada/Atlantic
Canada/Central
Canada/East-Saskatchewan
Canada/Eastern
Canada/Mountain
Canada/Newfoundland
Canada/Pacific
Canada/Saskatchewan
Canada/Yukon
Chile/Continental
Chile/EasterIsland
Cuba
EET
EST
EST5EDT
Egypt
Eire
Etc/GMT
Etc/GMT+0
Etc/GMT+1
Etc/GMT+10
Etc/GMT+11
Etc/GMT+12
Etc/GMT+2
Etc/GMT+3
Etc/GMT+4
Etc/GMT+5
Etc/GMT+6
Etc/GMT+7
Etc/GMT+8
Etc/GMT+9
Etc/GMT-0
Etc/GMT-1
Etc/GMT-10
Etc/GMT-11
Etc/GMT-12
Etc/GMT-13
Etc/GMT-14
Etc/GMT-2
Etc/GMT-3
Etc/GMT-4
Etc/GMT-5
Etc/GMT-6
Etc/GMT-7
Etc/GMT-8
Etc/GMT-9
Etc/GMT0
Etc/Greenwich
Etc/UCT
Etc/UTC
Etc/Universal
Etc/Zulu
Europe/Amsterdam
Europe/Andorra
Europe/Athens
Europe/Belfast
Europe/Belgrade
Europe/Berlin
Europe/Bratislava
Europe/Brussels
Europe/Bucharest
Europe/Budapest
Europe/Chisinau
Europe/Copenhagen
Europe/Dublin
Europe/Gibraltar
Europe/Guernsey
Europe/Helsinki
Europe/Isle_of_Man
Europe/Istanbul
Europe/Jersey
Europe/Kaliningrad
Europe/Kiev
Europe/Lisbon
Europe/Ljubljana
Europe/London
Europe/Luxembourg
Europe/Madrid
Europe/Malta
Europe/Mariehamn
Europe/Minsk
Europe/Monaco
Europe/Moscow
Europe/Nicosia
Europe/Oslo
Europe/Paris
Europe/Podgorica
Europe/Prague
Europe/Riga
Europe/Rome
Europe/Samara
Europe/San_Marino
Europe/Sarajevo
Europe/Simferopol
Europe/Skopje
Europe/Sofia
Europe/Stockholm
Europe/Tallinn
Europe/Tirane
Europe/Tiraspol
Europe/Uzhgorod
Europe/Vaduz
Europe/Vatican
Europe/Vienna
Europe/Vilnius
Europe/Volgograd
Europe/Warsaw
Europe/Zagreb
Europe/Zaporozhye
Europe/Zurich
GB
GB-Eire
GMT
GMT+0
GMT-0
GMT0
Greenwich
HST
Hongkong
Iceland
Indian/Antananarivo
Indian/Chagos
Indian/Christmas
Indian/Cocos
Indian/Comoro
Indian/Kerguelen
Indian/Mahe
Indian/Maldives
Indian/Mauritius
Indian/Mayotte
Indian/Reunion
Iran
Israel
Jamaica
Japan
Kwajalein
Libya
MET
MST
MST7MDT
Mexico/BajaNorte
Mexico/BajaSur
Mexico/General
NZ
NZ-CHAT
Navajo
PRC
PST8PDT
Pacific/Apia
Pacific/Auckland
Pacific/Chatham
Pacific/Chuuk
Pacific/Easter
Pacific/Efate
Pacific/Enderbury
Pacific/Fakaofo
Pacific/Fiji
Pacific/Funafuti
Pacific/Galapagos
Pacific/Gambier
Pacific/Guadalcanal
Pacific/Guam
Pacific/Honolulu
Pacific/Johnston
Pacific/Kiritimati
Pacific/Kosrae
Pacific/Kwajalein
Pacific/Majuro
Pacific/Marquesas
Pacific/Midway
Pacific/Nauru
Pacific/Niue
Pacific/Norfolk
Pacific/Noumea
Pacific/Pago_Pago
Pacific/Palau
Pacific/Pitcairn
Pacific/Pohnpei
Pacific/Ponape
Pacific/Port_Moresby
Pacific/Rarotonga
Pacific/Saipan
Pacific/Samoa
Pacific/Tahiti
Pacific/Tarawa
Pacific/Tongatapu
Pacific/Truk
Pacific/Wake
Pacific/Wallis
Pacific/Yap
Poland
Portugal
ROC
ROK
Singapore
Turkey
UCT
US/Alaska
US/Aleutian
US/Arizona
US/Central
US/East-Indiana
US/Eastern
US/Hawaii
US/Indiana-Starke
US/Michigan
US/Mountain
US/Pacific
US/Pacific-New
US/Samoa
UTC
Universal
W-SU
WET
Zulu

回答 0

您可以使用列出所有可用的时区pytz.all_timezones

In [40]: import pytz
In [41]: pytz.all_timezones
Out[42]: 
['Africa/Abidjan',
 'Africa/Accra',
 'Africa/Addis_Ababa',
 ...]

还有pytz.common_timezones

In [45]: len(pytz.common_timezones)
Out[45]: 403

In [46]: len(pytz.all_timezones)
Out[46]: 563

You can list all the available timezones with pytz.all_timezones:

In [40]: import pytz
In [41]: pytz.all_timezones
Out[42]: 
['Africa/Abidjan',
 'Africa/Accra',
 'Africa/Addis_Ababa',
 ...]

There is also pytz.common_timezones:

In [45]: len(pytz.common_timezones)
Out[45]: 403

In [46]: len(pytz.all_timezones)
Out[46]: 563

回答 1

不要创建自己的列表pytz具有内置集:

import pytz
set(pytz.all_timezones_set)  
>>> {'Europe/Vienna', 'America/New_York', 'America/Argentina/Salta',..}

然后,您可以应用时区

import datetime
tz = pytz.timezone('Pacific/Johnston')
ct = datetime.datetime.now(tz=tz)
>>> ct.isoformat()
2017-01-13T11:29:22.601991-05:00

或者,如果你已经有了一个datetime对象TZ知道(试验过的):

# This timestamp is in UTC
my_ct = datetime.datetime.now(tz=pytz.UTC)

# Now convert it to another timezone
new_ct = my_ct.astimezone(tz)
>>> new_ct.isoformat()
2017-01-13T11:29:22.601991-05:00

Don’t create your own listpytz has a built-in set:

import pytz
set(pytz.all_timezones_set)  
>>> {'Europe/Vienna', 'America/New_York', 'America/Argentina/Salta',..}

You can then apply a timezone:

import datetime
tz = pytz.timezone('Pacific/Johnston')
ct = datetime.datetime.now(tz=tz)
>>> ct.isoformat()
2017-01-13T11:29:22.601991-05:00

Or if you already have a datetime object that is TZ aware (not naive):

# This timestamp is in UTC
my_ct = datetime.datetime.now(tz=pytz.UTC)

# Now convert it to another timezone
new_ct = my_ct.astimezone(tz)
>>> new_ct.isoformat()
2017-01-13T11:29:22.601991-05:00

回答 2

时区名称是指定时区的唯一可靠方法。

您可以在此处找到时区名称列表:http : //en.wikipedia.org/wiki/List_of_tz_database_time_zones 请注意,此列表包含很多别名,例如美国/东部表示时区,通常称为America / New_York。

如果您以编程方式希望从zoneinfo数据库中创建此列表,则可以从zoneinfo数据库中的zone.tab文件中对其进行编译。我认为pytz没有API来获取它们,我也不认为它会非常有用。

The timezone name is the only reliable way to specify the timezone.

You can find a list of timezone names here: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones Note that this list contains a lot of alias names, such as US/Eastern for the timezone that is properly called America/New_York.

If you programatically want to create this list from the zoneinfo database you can compile it from the zone.tab file in the zoneinfo database. I don’t think pytz has an API to get them, and I also don’t think it would be very useful.


回答 3

这里是国家代码,名称,大洲,大写字母和pytz时区的Python列表。

countries = [
{'timezones': ['Europe/Paris'], 'code': 'FR', 'continent': 'Europe', 'name': 'France', 'capital': 'Paris'}
{'timezones': ['Africa/Kampala'], 'code': 'UG', 'continent': 'Africa', 'name': 'Uganda', 'capital': 'Kampala'},
{'timezones': ['Asia/Colombo'], 'code': 'LK', 'continent': 'Asia', 'name': 'Sri Lanka', 'capital': 'Sri Jayewardenepura Kotte'},
{'timezones': ['Asia/Riyadh'], 'code': 'SA', 'continent': 'Asia', 'name': 'Saudi Arabia', 'capital': 'Riyadh'},
{'timezones': ['Africa/Luanda'], 'code': 'AO', 'continent': 'Africa', 'name': 'Angola', 'capital': 'Luanda'},    
{'timezones': ['Europe/Vienna'], 'code': 'AT', 'continent': 'Europe', 'name': 'Austria', 'capital': 'Vienna'},
{'timezones': ['Asia/Calcutta'], 'code': 'IN', 'continent': 'Asia', 'name': 'India', 'capital': 'New Delhi'},
{'timezones': ['Asia/Dubai'], 'code': 'AE', 'continent': 'Asia', 'name': 'United Arab Emirates', 'capital': 'Abu Dhabi'},
{'timezones': ['Europe/London'], 'code': 'GB', 'continent': 'Europe', 'name': 'United Kingdom', 'capital': 'London'},
]

有关完整列表: Gist Github

希望能帮助到你。

Here, Python list of country codes, names, continents, capitals, and pytz timezones.

countries = [
{'timezones': ['Europe/Paris'], 'code': 'FR', 'continent': 'Europe', 'name': 'France', 'capital': 'Paris'}
{'timezones': ['Africa/Kampala'], 'code': 'UG', 'continent': 'Africa', 'name': 'Uganda', 'capital': 'Kampala'},
{'timezones': ['Asia/Colombo'], 'code': 'LK', 'continent': 'Asia', 'name': 'Sri Lanka', 'capital': 'Sri Jayewardenepura Kotte'},
{'timezones': ['Asia/Riyadh'], 'code': 'SA', 'continent': 'Asia', 'name': 'Saudi Arabia', 'capital': 'Riyadh'},
{'timezones': ['Africa/Luanda'], 'code': 'AO', 'continent': 'Africa', 'name': 'Angola', 'capital': 'Luanda'},    
{'timezones': ['Europe/Vienna'], 'code': 'AT', 'continent': 'Europe', 'name': 'Austria', 'capital': 'Vienna'},
{'timezones': ['Asia/Calcutta'], 'code': 'IN', 'continent': 'Asia', 'name': 'India', 'capital': 'New Delhi'},
{'timezones': ['Asia/Dubai'], 'code': 'AE', 'continent': 'Asia', 'name': 'United Arab Emirates', 'capital': 'Abu Dhabi'},
{'timezones': ['Europe/London'], 'code': 'GB', 'continent': 'Europe', 'name': 'United Kingdom', 'capital': 'London'},
]

For full list : Gist Github

Hope, It helps.


回答 4

它们似乎由此处找到的tz数据库时区填充。

在此处输入图片说明

They appear to be populated by the tz database time zones found here.

enter image description here


回答 5

编辑:如果您不进一步拒绝这个答案,我将不胜感激。这个答案是错误的,但我宁愿将其保留为历史记录。尽管pytz接口是否容易出错是有争议的,但它可以完成dateutil.tz无法做到的事情,尤其是在过去或将来的夏时制方面。我已经在“ Python的时区”文章中坦白记录了我的经验。


如果您使用的是类似Unix的平台,建议您避免使用pytz,而只需查看/ usr / share / zoneinfo。dateutil.tz可以利用那里的信息。

以下代码展示了pytz可以解决的问题。当我第一次发现它时,我感到震惊。(有趣的是,yum在CentOS 7上安装的pytz不会出现此问题。)

import pytz
import dateutil.tz
from datetime import datetime
print((datetime(2017,2,13,14,29,29, tzinfo=pytz.timezone('Asia/Shanghai'))
     - datetime(2017,2,13,14,29,29, tzinfo=pytz.timezone('UTC')))
     .total_seconds())
print((datetime(2017,2,13,14,29,29, tzinfo=dateutil.tz.gettz('Asia/Shanghai'))
     - datetime(2017,2,13,14,29,29, tzinfo=dateutil.tz.tzutc()))
     .total_seconds())

-29160.0
-28800.0

即pytz创建的时区是真实的当地时间,而不是人们观察到的标准当地时间。上海符合+0800,而不是pytz建议的+0806:

pytz.timezone('Asia/Shanghai')
<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>

编辑:感谢Mark Ransom的评论和不赞成,现在我知道我以错误的方式使用pytz。总之,您不应将的结果传递pytz.timezone(…)datetime,而应将传递datetime给其localize方法。

尽管有他的论点(而且我的缺点是不能更仔细地阅读pytz文档),但我将保留这个答案。我以一种方式(尽管不使用pytz枚举受支持的时区)来回答问题,因为我相信pytz不能提供正确的解决方案。尽管我的想法是错误的,但是此答案仍提供一些信息,恕我直言,这可能会对对此问题感兴趣的人有用。Pytz 正确的做事方式是违反直觉的。哎呀,如果pytz创建的tzinfo不应该被直接使用datetime,则它应该是另一种类型。pytz接口设计得很糟糕。Mark提供的链接表明,很多人(不仅是我)已经被pytz界面误导了。

EDIT: I would appreciate it if you do not downvote this answer further. This answer is wrong, but I would rather retain it as a historical note. While it is arguable whether the pytz interface is error-prone, it can do things that dateutil.tz cannot do, especially regarding daylight-saving in the past or in the future. I have honestly recorded my experience in an article “Time zones in Python”.


If you are on a Unix-like platform, I would suggest you avoid pytz and look just at /usr/share/zoneinfo. dateutil.tz can utilize the information there.

The following piece of code shows the problem pytz can give. I was shocked when I first found it out. (Interestingly enough, the pytz installed by yum on CentOS 7 does not exhibit this problem.)

import pytz
import dateutil.tz
from datetime import datetime
print((datetime(2017,2,13,14,29,29, tzinfo=pytz.timezone('Asia/Shanghai'))
     - datetime(2017,2,13,14,29,29, tzinfo=pytz.timezone('UTC')))
     .total_seconds())
print((datetime(2017,2,13,14,29,29, tzinfo=dateutil.tz.gettz('Asia/Shanghai'))
     - datetime(2017,2,13,14,29,29, tzinfo=dateutil.tz.tzutc()))
     .total_seconds())

-29160.0
-28800.0

I.e. the timezone created by pytz is for the true local time, instead of the standard local time people observe. Shanghai conforms to +0800, not +0806 as suggested by pytz:

pytz.timezone('Asia/Shanghai')
<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>

EDIT: Thanks to Mark Ransom’s comment and downvote, now I know I am using pytz the wrong way. In summary, you are not supposed to pass the result of pytz.timezone(…) to datetime, but should pass the datetime to its localize method.

Despite his argument (and my bad for not reading the pytz documentation more carefully), I am going to keep this answer. I was answering the question in one way (how to enumerate the supported timezones, though not with pytz), because I believed pytz did not provide a correct solution. Though my belief was wrong, this answer is still providing some information, IMHO, which is potentially useful to people interested in this question. Pytz’s correct way of doing things is counter-intuitive. Heck, if the tzinfo created by pytz should not be directly used by datetime, it should be a different type. The pytz interface is simply badly designed. The link provided by Mark shows that many people, not just me, have been misled by the pytz interface.


回答 6

我认为这是pytz库的设计缺陷。使用偏移量指定时区应该更可靠,例如

pytz.construct("UTC-07:00")

给您加拿大/太平洋时区。

In my opinion this is a design flaw of pytz library. It should be more reliable to specify a timezone using the offset, e.g.

pytz.construct("UTC-07:00")

which gives you Canada/Pacific timezone.


Django可扩展吗?[关闭]

问题:Django可扩展吗?[关闭]

我正在使用Django构建Web应用程序。我选择Django的原因是:

  • 我想使用免费/开源工具。
  • 我喜欢Python,并认为它是一种长期的语言,而对于Ruby,我不确定,PHP似乎是一个学习上的麻烦。
  • 我正在为一个想法构建原型,并且对未来没有太多考虑。开发速度是主要因素,我已经了解Python。
  • 我知道,如果将来我选择迁移到Google App Engine,将会更容易。
  • 我听说Django很“不错”。

现在,我开始考虑发布作品了,我开始担心规模。我发现的有关Django扩展功能的唯一信息是Django团队提供的(我并不是说要忽略它们,但这显然不是客观信息…)。

我的问题:

  • 今天在Django上构建的“最大”网站是什么?(我主要通过用户流量来衡量规模)
  • Django可以每天处理100,000个用户,每个用户访问几个小时吗?
  • 像Stack Overflow这样的网站可以在Django上运行吗?

I’m building a web application with Django. The reasons I chose Django were:

  • I wanted to work with free/open-source tools.
  • I like Python and feel it’s a long-term language, whereas regarding Ruby I wasn’t sure, and PHP seemed like a huge hassle to learn.
  • I’m building a prototype for an idea and wasn’t thinking too much about the future. Development speed was the main factor, and I already knew Python.
  • I knew the migration to Google App Engine would be easier should I choose to do so in the future.
  • I heard Django was “nice”.

Now that I’m getting closer to thinking about publishing my work, I start being concerned about scale. The only information I found about the scaling capabilities of Django is provided by the Django team (I’m not saying anything to disregard them, but this is clearly not objective information…).

My questions:

  • What’s the “largest” site that’s built on Django today? (I measure size mostly by user traffic)
  • Can Django deal with 100,000 users daily, each visiting the site for a couple of hours?
  • Could a site like Stack Overflow run on Django?

回答 0

  1. “当今在Django上最大的网站是什么?”

    没有一个地方可以收集有关Django构建的网站上的流量的信息,因此我将不得不使用来自不同位置的数据来刺探它。首先,在Django项目主页的首页上有Django站点列表,然后在djangosites.org上有Django构建的站点列表。浏览列表并挑选一些我知道流量不错的网站,我们看到:

  2. “ Django每天可以处理100,000个用户,每个用户访问网站几个小时吗?”

    是的,请参见上文。

  3. “像Stack Overflow这样的网站可以在Django上运行吗?”

    我的直觉是肯定的,但是正如其他人回答并且Mike Malone在演讲中提到的那样,数据库设计至关重要。如果我们可以找到任何可靠的流量统计信息,也可以在www.cnprog.com上找到有力的证明。无论如何,将一堆Django模型放在一起不仅仅是发生的事情:)

当然,还有更多感兴趣的网站和博客作者,但是我必须在某个地方停下来!


关于使用Django构建高流量网站michaelmoore.com的博客文章,描述为排名前10,000的网站Quantcast统计信息Competition.com统计数据


(*)编辑的作者,包括此类参考文献,曾在该项目中担任外包开发人员。

  1. “What are the largest sites built on Django today?”

    There isn’t any single place that collects information about traffic on Django built sites, so I’ll have to take a stab at it using data from various locations. First, we have a list of Django sites on the front page of the main Django project page and then a list of Django built sites at djangosites.org. Going through the lists and picking some that I know have decent traffic we see:

  2. “Can Django deal with 100,000 users daily, each visiting the site for a couple of hours?”

    Yes, see above.

  3. “Could a site like Stack Overflow run on Django?”

    My gut feeling is yes but, as others answered and Mike Malone mentions in his presentation, database design is critical. Strong proof might also be found at www.cnprog.com if we can find any reliable traffic stats. Anyway, it’s not just something that will happen by throwing together a bunch of Django models :)

There are, of course, many more sites and bloggers of interest, but I have got to stop somewhere!


Blog post about Using Django to build high-traffic site michaelmoore.com described as a top 10,000 website. Quantcast stats and compete.com stats.


(*) The author of the edit, including such reference, used to work as outsourced developer in that project.


回答 1

我们正在进行负载测试。我们认为我们可以支持240个并发请求(持续24×7的每秒120次命中),而服务器性能没有任何显着降低。那将是每小时432,000次点击。响应时间并不短(我们的交易量很大),但是随着负载的增加,我们的基准性能不会降低。

我们正在使用Apache前端Django和MySQL。操作系统是Red Hat Enterprise Linux(RHEL)。64位。对于Django,我们在守护程序模式下使用mod_wsgi。除了接受默认值外,我们没有进行任何缓存或数据库优化。

我们全都位于具有(我认为)32Gb RAM的64位Dell上的一个VM中。

由于20个或200个并发用户的性能几乎相同,因此我们不需要花费大量时间“调整”。相反,我们只需要通过常规SSL性能改进,常规数据库设计和实现(索引等),常规防火墙性能改进等来保持基本性能。

我们要衡量的是我们的负载测试笔记本电脑在15个运行16个请求并发线程的进程的疯狂工作量下苦苦挣扎。

We’re doing load testing now. We think we can support 240 concurrent requests (a sustained rate of 120 hits per second 24×7) without any significant degradation in the server performance. That would be 432,000 hits per hour. Response times aren’t small (our transactions are large) but there’s no degradation from our baseline performance as the load increases.

We’re using Apache front-ending Django and MySQL. The OS is Red Hat Enterprise Linux (RHEL). 64-bit. We use mod_wsgi in daemon mode for Django. We’ve done no cache or database optimization other than to accept the defaults.

We’re all in one VM on a 64-bit Dell with (I think) 32Gb RAM.

Since performance is almost the same for 20 or 200 concurrent users, we don’t need to spend huge amounts of time “tweaking”. Instead we simply need to keep our base performance up through ordinary SSL performance improvements, ordinary database design and implementation (indexing, etc.), ordinary firewall performance improvements, etc.

What we do measure is our load test laptops struggling under the insane workload of 15 processes running 16 concurrent threads of requests.


回答 2

不确定每天的访问次数,但以下是一些大型Django网站的示例:

这是Quora高流量Django站点列表的链接。

Not sure about the number of daily visits but here are a few examples of large Django sites:

Here is a link to list of high traffic Django sites on Quora.


回答 3

今天在Django上构建的“最大”网站是什么?(我主要通过用户流量来衡量规模)

在美国,是玛哈洛(Mahalo)。有人告诉我他们每个月处理大约1000万个唯一身份。现在,在2019年,Mahalo由Ruby on Rails提供支持。

国外,Globo网络(巴西新闻,体育和娱乐网站的网络);Alexa将其排在全球前100名(目前排名第80位)。

其他著名的Django用户包括PBS,国家地理,探索,NASA(实际上是NASA内的许多不同部门)和国会图书馆。

Django每天可以处理10万个用户,每个用户访问该网站几个小时吗?

是的-但前提是您正确编写了应用程序,并且拥有足够的硬件。Django不是万能的子弹。

像StackOverflow这样的网站可以在Django上运行吗?

是的(但见上文)。

从技术角度出发,轻而易举:尝试一下soclone。在流量方面,每月以不超过一百万的唯一身份竞争钉住StackOverflow。我可以命名至少十个Django网站,其流量比SO多。

What’s the “largest” site that’s built on Django today? (I measure size mostly by user traffic)

In the US, it was Mahalo. I’m told they handle roughly 10 million uniques a month. Now, in 2019, Mahalo is powered by Ruby on Rails.

Abroad, the Globo network (a network of news, sports, and entertainment sites in Brazil); Alexa ranks them in to top 100 globally (around 80th currently).

Other notable Django users include PBS, National Geographic, Discovery, NASA (actually a number of different divisions within NASA), and the Library of Congress.

Can Django deal with 100k users daily, each visiting the site for a couple of hours?

Yes — but only if you’ve written your application right, and if you’ve got enough hardware. Django’s not a magic bullet.

Could a site like StackOverflow run on Django?

Yes (but see above).

Technology-wise, easily: see soclone for one attempt. Traffic-wise, compete pegs StackOverflow at under 1 million uniques per month. I can name at least dozen Django sites with more traffic than SO.


回答 4

扩展Web应用程序与Web框架或语言无关,而与您的体系结构有关。它涉及到如何处理浏览器缓存,数据库缓存,如何使用非标准持久性提供程序(例如CouchDB),数据库的调整方式以及许多其他内容。

Scaling Web apps is not about web frameworks or languages, is about your architecture. It’s about how you handle you browser cache, your database cache, how you use non-standard persistence providers (like CouchDB), how tuned is your database and a lot of other stuff…


回答 5

扮演恶魔的拥护者:

您应该查看Cal Henderson提供的DjangoCon 2008主题演讲,题目为“为什么我讨厌Django”,其中他几乎涵盖了您可能想要在高流量网站中执行的Django缺少的所有事项。在这一天结束时,你有,因为它把所有这些以开放的心态完全有可能写出Django的应用包含的规模,但我认为这是一个很好的介绍和有关你的问题。

Playing devil’s advocate a little bit:

You should check the DjangoCon 2008 Keynote, delivered by Cal Henderson, titled “Why I hate Django” where he pretty much goes over everything Django is missing that you might want to do in a high traffic website. At the end of the day you have to take this all with an open mind because it is perfectly possible to write Django apps that scale, but I thought it was a good presentation and relevant to your question.


回答 6

我知道的最大的django网站是《华盛顿邮报》,这肯定表明它可以很好地扩展。

好的设计决策可能会对性能产生更大的影响。Twitter通常被认为是一个网站,它通过另一个基于动态解释语言的Web框架Ruby on Rails来体现性能问题-但Twitter工程师表示,该框架并没有像他们早先做出的某些数据库设计选择那样重要上。

Django与memcached配合得很好,并提供了一些用于管理缓存的类,您可以在其中解决大部分性能问题。在线交付的内容实际上比后端要重要的多-使用yslow之类的工具对于高性能Web应用程序至关重要。您始终可以在后端投入更多的硬件,但不能更改用户带宽。

The largest django site I know of is the Washington Post, which would certainly indicate that it can scale well.

Good design decisions probably have a bigger performance impact than anything else. Twitter is often cited as a site which embodies the performance issues with another dynamic interpreted language based web framework, Ruby on Rails – yet Twitter engineers have stated that the framework isn’t as much an issue as some of the database design choices they made early on.

Django works very nicely with memcached and provides some classes for managing the cache, which is where you would resolve the majority of your performance issues. What you deliver on the wire is almost more important than your backend in reality – using a tool like yslow is critical for a high performance web application. You can always throw more hardware at your backend, but you can’t change your users bandwidth.


回答 7

我上周参加了EuroDjangoCon会议,这是几场讲座的主题-包括最大的基于Django的网站Pownce的创建者(这里的一个演讲的幻灯片)。主要信息是,您不必担心Django,而需要进行适当的缓存,负载平衡,数据库优化等工作。

Django实际上对大多数这些东西都有钩子-特别是缓存非常容易。

I was at the EuroDjangoCon conference the other week, and this was the subject of a couple of talks – including from the founders of what was the largest Django-based site, Pownce (slides from one talk here). The main message is that it’s not Django you have to worry about, but things like proper caching, load balancing, database optimisation, etc.

Django actually has hooks for most of those things – caching, in particular, is made very easy.


回答 8

我确定您正在寻找一个更可靠的答案,但是我能想到的最明显的客观验证是Google推动Django与它的App Engine框架一起使用。如果有人定期了解并处理可扩展性,那就是Google。根据我的阅读,最大的限制因素似乎是数据库后端,这就是Google使用自己的数据库的原因…

I’m sure you’re looking for a more solid answer, but the most obvious objective validation I can think of is that Google pushes Django for use with its App Engine framework. If anybody knows about and deals with scalability on a regular basis, it’s Google. From what I’ve read, the most limiting factor seems to be the database back-end, which is why Google uses their own…


回答 9

如高性能 Django书中所述, 并通过本Cal Henderson

请参阅下面提到的更多详细信息:

听到人们说“ Django无法扩展”的情况并不少见。根据您的看法,该陈述是完全正确的,也可能是完全错误的。Django本身无法扩展。

Ruby on Rails,Flask,PHP或数据库驱动的动态网站使用的任何其他语言也可以这样说。

不过,好消息是Django与一套缓存和负载平衡工具进行了精美的交互,这将使其能够扩展到最大流量。

与您在网上阅读的内容相反,它可以这样做,而无需替换通常标为“过慢”的核心组件,例如数据库ORM或模板层。

Disqus每月提供超过80亿的页面浏览量。那些数字很大。

这些团队已经证明Django确实可以扩展。我们在林肯环路的经验对此提供了支持。

我们已经建立了大型的Django网站,这些网站能够在Reddit主页上度过一天而又不费吹灰之力。

到目前为止,Django的扩展成功案例几乎不胜枚举。

它支持Disqus,Instagram和Pinterest。需要更多证据吗?Instagram仅3位工程师(其中2位没有后端开发)就能在Django上维持超过3000万用户

As stated in High Performance Django Book and Go through this Cal Henderson

See further details as mentioned below:

It’s not uncommon to hear people say “Django doesn’t scale”. Depending on how you look at it, the statement is either completely true or patently false. Django, on its own, doesn’t scale.

The same can be said of Ruby on Rails, Flask, PHP, or any other language used by a database-driven dynamic website.

The good news, however, is that Django interacts beautifully with a suite of caching and load balancing tools that will allow it to scale to as much traffic as you can throw at it.

Contrary to what you may have read online, it can do so without replacing core components often labeled as “too slow” such as the database ORM or the template layer.

Disqus serves over 8 billion page views per month. Those are some huge numbers.

These teams have proven Django most certainly does scale. Our experience here at Lincoln Loop backs it up.

We’ve built big Django sites capable of spending the day on the Reddit homepage without breaking a sweat.

Django’s scaling success stories are almost too numerous to list at this point.

It backs Disqus, Instagram, and Pinterest. Want some more proof? Instagram was able to sustain over 30 million users on Django with only 3 engineers (2 of which had no back-end development


回答 10

今天,我们使用许多Web应用程序和网站来满足我们的需求。它们中的大多数非常有用。我将向您展示python或django使用的其中一些。

华盛顿邮报

《华盛顿邮报》的网站是伴随他们的每日报纸而广为流行的在线新闻来源。Django Web框架可以轻松处理其大量的视图和流量。 Washington Post - 52.2 million unique visitors (March, 2015)

美国宇航局

国家航空航天局的官方网站是查找有关其正在进行的太空探索的新闻,图片和视频的地方。这个Django网站可以轻松处理大量的视图和流量。 2 million visitors monthly

守护者

《卫报》是英国《卫报》媒体集团所有的新闻和媒体网站。它几乎包含了《卫报》和《观察家》报纸的所有内容。这些巨大的数据由Django处理。 The Guardian (commenting system) - 41,6 million unique visitors (October, 2014)

的YouTube

我们都知道YouTube是上传猫视频的地方,但失败了。作为现有的最受欢迎的网站之一,它为我们提供了无尽的视频娱乐时间。Python编程语言为其提供了强大支持,并为我们所喜爱的功能提供了支持。

投递箱

DropBox引发了在线文档存储革命,这已成为日常生活的一部分。现在,我们几乎将所有内容都存储在云中。Dropbox使我们能够使用Python的功能存储,同步和共享几乎所有内容。

调查Monkey

Survey Monkey是最大的在线调查公司。他们每天可以在重写的Python网站上处理超过一百万个响应。

Quora

Quora是在线提问和接收社区答案的第一人。这些社区成员在他们的Python网站上回答,编辑和组织了相关结果。

有点

Bitly URL缩短服务和分析的大多数代码都是使用Python构建的。他们的服务每天可以处理数亿个事件。

Reddit

Reddit被称为互联网的首页。这是一个在线查找基于数千种不同类别的信息或娱乐的地方。帖子和链接由用户生成,并通过投票提升到顶部。Reddit的许多功能都依靠Python来实现。

希普姆克

Hipmunk是一个在线消费者旅游网站,它比较热门旅游网站以找到最优惠的价格。这个Python网站的工具可让您找到目的地的最便宜的酒店和机票。

单击此处了解更多: 25个最受欢迎的python和django网站什么是在Django上运行的知名站点

Today we use many web apps and sites for our needs. Most of them are highly useful. I will show you some of them used by python or django.

Washington Post

The Washington Post’s website is a hugely popular online news source to accompany their daily paper. Its’ huge amount of views and traffic can be easily handled by the Django web framework. Washington Post - 52.2 million unique visitors (March, 2015)

NASA

The National Aeronautics and Space Administration’s official website is the place to find news, pictures, and videos about their ongoing space exploration. This Django website can easily handle huge amounts of views and traffic. 2 million visitors monthly

The Guardian

The Guardian is a British news and media website owned by the Guardian Media Group. It contains nearly all of the content of the newspapers The Guardian and The Observer. This huge data is handled by Django. The Guardian (commenting system) - 41,6 million unique visitors (October, 2014)

YouTube

We all know YouTube as the place to upload cat videos and fails. As one of the most popular websites in existence, it provides us with endless hours of video entertainment. The Python programming language powers it and the features we love.

DropBox

DropBox started the online document storing revolution that has become part of daily life. We now store almost everything in the cloud. Dropbox allows us to store, sync, and share almost anything using the power of Python.

Survey Monkey

Survey Monkey is the largest online survey company. They can handle over one million responses every day on their rewritten Python website.

Quora

Quora is the number one place online to ask a question and receive answers from a community of individuals. On their Python website relevant results are answered, edited, and organized by these community members.

Bitly

A majority of the code for Bitly URL shortening services and analytics are all built with Python. Their service can handle hundreds of millions of events per day.

Reddit

Reddit is known as the front page of the internet. It is the place online to find information or entertainment based on thousands of different categories. Posts and links are user generated and are promoted to the top through votes. Many of Reddit’s capabilities rely on Python for their functionality.

Hipmunk

Hipmunk is an online consumer travel site that compares the top travel sites to find you the best deals. This Python website’s tools allow you to find the cheapest hotels and flights for your destination.

Click here for more: 25-of-the-most-popular-python-and-django-websites, What-are-some-well-known-sites-running-on-Django


回答 11

我认为我们不妨将2011年苹果年度最佳应用程序Instagram(Instagram)添加到大量使用django的列表中。

I think we might as well add Apple’s App of the year for 2011, Instagram, to the list which uses django intensively.


回答 12

是的,它可以。可以是带Python的Django或Ruby on Rails。它仍然会扩展。

有几种不同的技术。首先,缓存无法扩展。除了硬件平衡器之外,您可能还具有以nginx作为前端平衡的多个应用程序服务器。为了扩展数据库方面,如果您采用RDBMS方式,则可以在MySQL / PostgreSQL中使用读取从属进行相当大的扩展。

Django中的高流量网站的一些很好的例子可能是:

  • 当他们还在那儿的时候就穿衣服
  • 铁饼(通用共享评论管理器)
  • 所有与报纸相关的网站:《华盛顿邮报》等。

您可以放心。

Yes it can. It could be Django with Python or Ruby on Rails. It will still scale.

There are few different techniques. First, caching is not scaling. You could have several application servers balanced with nginx as the front in addition to hardware balancer(s). To scale on the database side you can go pretty far with read slave in MySQL / PostgreSQL if you go the RDBMS way.

Some good examples of heavy traffic websites in Django could be:

  • Pownce when they were still there.
  • Discus (generic shared comments manager)
  • All the newspaper related websites: Washington Post and others.

You can feel safe.


回答 13

以下是Django中一些比较引人注目的内容的列表:

  1. 监护人的“ 调查议员的费用 ”应用程序

  2. Politifact.com(这是一篇有关(正面)体验的博客文章。该网站赢得了普利策奖)。

  3. 纽约时报的代表应用程序

  4. 每个块

  5. WaPo的一名程序员Peter Harkins 在他的博客中列出了他们用Django构建的所有内容

  6. 它有些旧,但是《洛杉矶时报》的某人对他们为什么选择Django 进行了基本概述

  7. 洋葱的AV俱乐部最近从(我认为Drupal)转移到了Django。

我想象这些网站中的许多网站每天的点击量可能超过10万次。Django当然可以每天点击10万次甚至更多。但是YMMV会根据您所构建的内容将您的特定网站放到那里。

在Django级别上,有一些缓存选项(例如,在memcached中缓存查询集和视图可以解决奇迹)以及其他方面(如Squid之类的上游缓存)。数据库服务器规范也将是一个因素(通常是挥霍的地方),以及您对其进行的优化程度。例如,不要以为Django会正确设置索引。不要以为默认的PostgreSQLMySQL配置是正确的配置。

此外,如果这是很慢的话,您总是可以选择让多个应用程序服务器运行Django,并在其前面安装软件或硬件负载平衡器。

最后,您是否要在与Django相同的服务器上提供静态内容?您使用的是Apache还是nginxlighttpd之类的东西?您能负担得起将CDN用于静态内容吗?这些都是要考虑的事情,但这都是非常投机的。每天10万次点击不是唯一的变量:您要花费多少?您拥有多少专业知识来管理所有这些组件?您需要花费多少时间将它们整合在一起?

Here’s a list of some relatively high-profile things built in Django:

  1. The Guardian’s “Investigate your MP’s expenses” app

  2. Politifact.com (here’s a Blog post talking about the (positive) experience. Site won a Pulitzer.

  3. NY Times’ Represent app

  4. EveryBlock

  5. Peter Harkins, one of the programmers over at WaPo, lists all the stuff they’ve built with Django on his blog

  6. It’s a little old, but someone from the LA Times gave a basic overview of why they went with Django.

  7. The Onion’s AV Club was recently moved from (I think Drupal) to Django.

I imagine a number of these these sites probably gets well over 100k+ hits per day. Django can certainly do 100k hits/day and more. But YMMV in getting your particular site there depending on what you’re building.

There are caching options at the Django level (for example caching querysets and views in memcached can work wonders) and beyond (upstream caches like Squid). Database Server specifications will also be a factor (and usually the place to splurge), as is how well you’ve tuned it. Don’t assume, for example, that Django’s going set up indexes properly. Don’t assume that the default PostgreSQL or MySQL configuration is the right one.

Furthermore, you always have the option of having multiple application servers running Django if that is the slow point, with a software or hardware load balancer in front.

Finally, are you serving static content on the same server as Django? Are you using Apache or something like nginx or lighttpd? Can you afford to use a CDN for static content? These are things to think about, but it’s all very speculative. 100k hits/day isn’t the only variable: how much do you want to spend? How much expertise do you have managing all these components? How much time do you have to pull it all together?


回答 14

YouTube的开发者拥护者在PyCon 2012上发表了有关缩放Python话题,这也与缩放Django有关。

YouTube拥有超过十亿的用户,并且YouTube基于Python构建。

The developer advocate for YouTube gave a talk about scaling Python at PyCon 2012, which is also relevant to scaling Django.

YouTube has more than a billion users, and YouTube is built on Python.


回答 15

我已经使用Django一年多了,它对组合模块化,可扩展性和开发速度的管理方式印象深刻。像任何技术一样,它也带有学习曲线。但是,Django社区提供的出色文档使学习曲线的难度大大降低。Django能够很好地处理我提出的所有问题。看起来它将能够很好地扩展到未来。

BidRodeo Penny Auctions是一个中等规模的Django支持的网站。这是一个非常动态的网站,每天确实处理大量的网页浏览。

I have been using Django for over a year now, and am very impressed with how it manages to combine modularity, scalability and speed of development. Like with any technology, it comes with a learning curve. However, this learning curve is made a lot less steep by the excellent documentation from the Django community. Django has been able to handle everything I have thrown at it really well. It looks like it will be able to scale well into the future.

BidRodeo Penny Auctions is a moderately sized Django powered website. It is a very dynamic website and does handle a good number of page views a day.


回答 16

请注意,如果您希望每天有10万名用户,并且一次处于活动状态数小时(意味着最多有2万名并发用户),那么您将需要大量服务器。SO拥有约15,000个注册用户,其中大多数人可能每天都不活跃。虽然大部分流量来自未注册的用户,但我猜想他们中很少有人会停留在网站上超过几分钟(即,他们遵循Google搜索结果然后离开)。

对于该数量,预计至少要有30台服务器……每台服务器仍然有1000个并发用户。

Note that if you’re expecting 100K users per day, that are active for hours at a time (meaning max of 20K+ concurrent users), you’re going to need A LOT of servers. SO has ~15,000 registered users, and most of them are probably not active daily. While the bulk of traffic comes from unregistered users, I’m guessing that very few of them stay on the site more than a couple minutes (i.e. they follow google search results then leave).

For that volume, expect at least 30 servers … which is still a rather heavy 1,000 concurrent users per server.


回答 17

今天在Django上构建的“最大”网站是什么?(我衡量大多是由用户流量的大小), Pinterest的
disqus.com
这里更多:https://www.shuup.com/en/blog/25-of-the-most-popular-python-and-django-websites/

Django是否可以每天处理100,000个用户,每个用户访问几个小时?
是的,但是使用适当的体系结构,数据库设计,缓存,负载平衡以及多个服务器或节点

像Stack Overflow这样的网站可以在Django上运行吗?
是的,只需要按照第二个问题中提到的答案

What’s the “largest” site that’s built on Django today? (I measure size mostly by user traffic) Pinterest
disqus.com
More here: https://www.shuup.com/en/blog/25-of-the-most-popular-python-and-django-websites/

Can Django deal with 100,000 users daily, each visiting the site for a couple of hours?
Yes but use proper architecture, database design, use of cache, use load balances and multiple servers or nodes

Could a site like Stack Overflow run on Django?
Yes just need to follow the answer mentioned in the 2nd question


回答 18

另一个示例是rasp.yandex.ru,俄罗斯的运输时间表服务。出席人数可以满足您的要求。

Another example is rasp.yandex.ru, Russian transport timetable service. Its attendance satisfies your requirements.


回答 19

如果您的网站上有一些静态内容,那么将Varnish服务器放在最前面将大大提高性能。即使是一个盒子,也可以轻松吐出100 Mbit / s的流量。

请注意,对于动态内容,使用Varnish之类的东西会变得更加棘手。

If you have a site with some static content, then putting a Varnish server in front will dramatically increase your performance. Even a single box can then easily spit out 100 Mbit/s of traffic.

Note that with dynamic content, using something like Varnish becomes a lot more tricky.


回答 20

我对Django的经验很少,但我确实记得《 Django书》中有一章,他们采访了运行某些较大Django应用程序的人员。 这是一个链接。 我想它可以提供一些见解。

它说curse.com是最大的Django应用程序之一,每月浏览量约为60-9000万。

My experience with Django is minimal but I do remember in The Django Book they have a chapter where they interview people running some of the larger Django applications. Here is a link. I guess it could provide some insights.

It says curse.com is one of the largest Django applications with around 60-90 million page views in a month.


回答 21

我使用Django为爱尔兰的国家广播公司开发高流量站点。它对我们很好。开发高性能站点不仅仅只是选择一个框架。框架将只是与最薄弱的环节一样强大的系统的一部分。如果问题是数据库查询速度慢或服务器或网络配置错误,则使用最新的框架“ X”不能解决您的性能问题。

I develop high traffic sites using Django for the national broadcaster in Ireland. It works well for us. Developing a high performance site is more than about just choosing a framework. A framework will only be one part of a system that is as strong as it’s weakest link. Using the latest framework ‘X’ won’t solve your performance issues if the problem is slow database queries or a badly configured server or network.


回答 22

尽管这里有很多不错的答案,但我只是想指出一点,没有人强调。

取决于应用

如果您的应用程序写时很少,那么从DB中读取的数据要比编写的要多得多。然后缩放django应该是相当琐碎的,哎呀,它带有一些相当不错的输出/视图缓存,可以直接使用。充分利用这一点,例如说redis作为缓存提供者,在它前面放置一个负载均衡器,启动n个实例,您应该能够处理非常大的流量。

现在,如果您必须每秒进行数千次复杂的写操作?不同的故事。Django将是一个错误的选择吗?好吧,不一定要取决于您如何真正设计解决方案以及您的要求是什么。

只是我的两分钱:-)

Even-though there have been a lot of great answers here, I just feel like pointing out, that nobody have put emphasis on..

It depends on the application

If you application is light on writes, as in you are reading a lot more data from the DB than you are writing. Then scaling django should be fairly trivial, heck, it comes with some fairly decent output/view caching straight out of the box. Make use of that, and say, redis as a cache provider, put a load balancer in front of it, spin up n-instances and you should be able to deal with a VERY large amount of traffic.

Now, if you have to do thousands of complex writes a second? Different story. Is Django going to be a bad choice? Well, not necessarily, depends on how you architect your solution really, and also, what your requirements are.

Just my two cents :-)


回答 23

您绝对可以在Django中运行高流量站点。在Django 1.0之前的版本中查看该版本,但仍在此处相关:http : //menendez.com/blog/launching-high-performance-django-site/

You can definitely run a high-traffic site in Django. Check out this pre-Django 1.0 but still relevant post here: http://menendez.com/blog/launching-high-performance-django-site/


回答 24

查看这个名为EveryBlock的微型新闻聚合

它完全用Django编写。实际上,他们是开发Django框架本身的人。

Check out this micro news aggregator called EveryBlock.

It’s entirely written in Django. In fact they are the people who developed the Django framework itself.


回答 25

问题不在于django是否可以扩展。

正确的方法是了解并了解在django / symfony / rails项目下可以很好地扩展的网络设计模式和工具。

一些想法可以是:

  • 多路复用。
  • 反向代理。例如:Nginx,光油
  • Memcache会话。例如:Redis
  • 在项目和数据库上进行集群化以实现负载平衡和容错:例如:Docker
  • 使用第三方存储资产。例如:Amazon S3

希望对您有所帮助。这是我到山上的小石头。

The problem is not to know if django can scale or not.

The right way is to understand and know which are the network design patterns and tools to put under your django/symfony/rails project to scale well.

Some ideas can be :

  • Multiplexing.
  • Inversed proxy. Ex : Nginx, Varnish
  • Memcache Session. Ex : Redis
  • Clusterization on your project and db for load balancing and fault tolerance : Ex : Docker
  • Use third party to store assets. Ex : Amazon S3

Hope it help a bit. This is my tiny rock to the mountain.


回答 26

如果您想使用开源,那么有很多选择。但是python是其中最好的,因为它有许多库和一个超棒的社区。这些是可能会改变您想法的一些原因:

  • Python非常好,但是它是一种解释型语言,因此速度很慢。但是有许多加速器和缓存服务可以部分解决此问题。

  • 如果您正在考虑快速发展,那么Ruby on Rails是最好的选择。此(ROR)框架的主要座右铭是为开发人员提供舒适的体验。如果您比较一下,Ruby和Python的语法几乎相同。

  • Google App Engine是一项非常好的服务,但是它将在您的范围内束缚您,您没有机会尝试新事物。取而代之的是,您可以使用Digital Ocean云,因为它最简单的液滴仅需每月支付5美元Heroku是另一项免费服务,您可以在其中部署产品。

  • 是! 是! 您所听到的是完全正确的,但这是一些使用其他技术的示例

    • Rails:Github,Twitter(以前),Shopify,Airbnb,Slideshare,Heroku等
    • PHP:Facebook,Wikipedia,Flickr,Yahoo,Tumbler,Mailchimp等。

结论是一种框架或语言无法为您做任何事情。更好的架构,设计和策略将为您提供可扩展的网站。Instagram是最大的例子,这个小团队正在管理如此庞大的数据。这是一个有关其架构必须阅读的博客

If you want to use Open source then there are many options for you. But python is best among them as it has many libraries and a super awesome community. These are a few reasons which might change your mind:

  • Python is very good but it is a interpreted language which makes it slow. But many accelerator and caching services are there which partly solve this problem.

  • If you are thinking about rapid development then Ruby on Rails is best among all. The main motto of this(ROR) framework is to give a comfortable experience to the developers. If you compare Ruby and Python both have nearly the same syntax.

  • Google App Engine is very good service but it will bind you in its scope, you don’t get chance to experiment new things. Instead of it you can use Digital Ocean cloud which will only take $5/Month charge for its simplest droplet. Heroku is another free service where you can deploy your product.

  • Yes! Yes! What you heard is totally correct but here are some examples which are using other technologies

    • Rails: Github, Twitter(previously), Shopify, Airbnb, Slideshare, Heroku etc.
    • PHP: Facebook, Wikipedia, Flickr, Yahoo, Tumbler, Mailchimp etc.

Conclusion is a framework or language won’t do everything for you. A better architecture, designing and strategy will give you a scalable website. Instagram is the biggest example, this small team is managing such huge data. Here is one blog about its architecture must read it.


回答 27

我不认为问题确实与Django缩放有关。

我真的建议您研究一下可以帮助您满足扩展需求的体系结构,如果您出错了,那么Django的性能将毫无意义。性能!=规模。您可以拥有一个性能惊人但不能扩展的系统,反之亦然。

您的应用程序数据库绑定了吗?如果是这样,那么您的规模问题也就在那里。您如何计划与Django中的数据库进行交互?当您的数据库无法以Django接受请求的速度处理请求时,会发生什么情况?当数据超过一台物理计算机时,会发生什么。您需要考虑如何计划应对这些情况。

此外,当您的流量超过一台应用服务器时会发生什么?在这种情况下,如何处理会话可能会很棘手,通常您可能需要无共享架构。同样,这取决于您的应用程序。

简而言之,语言不是决定规模的因素,语言是决定性能的因素(再次取决于您的应用程序,不同的语言表现不同)。是您的设计和体系结构使扩展成为现实。

希望对您有所帮助,如果您有任何疑问,将很乐意为您提供进一步的帮助。

I don’t think the issue is really about Django scaling.

I really suggest you look into your architecture that’s what will help you with your scaling needs.If you get that wrong there is no point on how well Django performs. Performance != Scale. You can have a system that has amazing performance but does not scale and vice versa.

Is your application database bound? If it is then your scale issues lay there as well. How are you planning on interacting with the database from Django? What happens when you database cannot process requests as fast as Django accepts them? What happens when your data outgrows one physical machine. You need to account for how you plan on dealing with those circumstances.

Moreover, What happens when your traffic outgrows one app server? how you handle sessions in this case can be tricky, more often than not you would probably require a shared nothing architecture. Again that depends on your application.

In short languages is not what determines scale, a language is responsible for performance(again depending on your applications, different languages perform differently). It is your design and architecture that makes scaling a reality.

I hope it helps, would be glad to help further if you have questions.


回答 28

一旦您的站点/应用程序开始增长,就必须平均分配任务,简而言之,优化各个方面,包括数据库,文件,图像,CSS等,并平衡负载与其他多种资源。或者,您为其腾出更多空间。大型站点必须实施CDN,云等最新技术。仅仅开发和调整应用程序并不能使您满意,其他组件也起着重要的作用。

Spreading the tasks evenly, in short optimizing each and every aspect including DBs, Files, Images, CSS etc. and balancing the load with several other resources is necessary once your site/application starts growing. OR you make some more space for it to grow. Implementation of latest technologies like CDN, Cloud are must with huge sites. Just developing and tweaking an application won’t give your the cent percent satisfation, other components also play an important role.