标签归档:Django

如何使用值列表过滤Django查询?

问题:如何使用值列表过滤Django查询?

我敢肯定这是一个微不足道的操作,但是我不知道它是如何完成的。

肯定有比这更聪明的东西:

ids = [1, 3, 6, 7, 9]

for id in ids:
    MyModel.objects.filter(pk=id)

我正在寻找将它们全部添加到一个查询中,例如:

MyModel.objects.filter(pk=[1, 3, 6, 7, 9])

如何使用值列表过滤Django查询?

I’m sure this is a trivial operation, but I can’t figure out how it’s done.

There’s got to be something smarter than this:

ids = [1, 3, 6, 7, 9]

for id in ids:
    MyModel.objects.filter(pk=id)

I’m looking to get them all in one query with something like:

MyModel.objects.filter(pk=[1, 3, 6, 7, 9])

How can I filter a Django query with a list of values?


回答 0

Django文档中

Blog.objects.filter(pk__in=[1, 4, 7])

From the Django documentation:

Blog.objects.filter(pk__in=[1, 4, 7])

回答 1

如果您有项目列表,并且想要从列表中检查可能的值,则不能使用=

sql查询就像SELECT * FROM mytable WHERE ids=[1, 3, 6, 7, 9]是不正确的。您必须为此使用in运算符,因此您的查询将类似于SELECT * FROM mytable WHERE ids in (1, 3, 6, 7, 9)Django提供的__in运算符。

When you have list of items and you want to check the possible values from the list then you can’t use =.

The sql query will be like SELECT * FROM mytable WHERE ids=[1, 3, 6, 7, 9] which is not true. You have to use in operator for this so you query will be like SELECT * FROM mytable WHERE ids in (1, 3, 6, 7, 9) for that Django provide __in operator.


回答 2

Django文档中

Blog.objects.in_bulk([1])
{1: <Blog: Beatles Blog>}

Blog.objects.in_bulk([1, 2])
{1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>}

Blog.objects.in_bulk([])
{}

Blog.objects.in_bulk()
{1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>, 3: <Blog: Django Weblog>}

Blog.objects.in_bulk(['beatles_blog'], field_name='slug')
{'beatles_blog': <Blog: Beatles Blog>}

From the Django documentation:

Blog.objects.in_bulk([1])
{1: <Blog: Beatles Blog>}

Blog.objects.in_bulk([1, 2])
{1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>}

Blog.objects.in_bulk([])
{}

Blog.objects.in_bulk()
{1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>, 3: <Blog: Django Weblog>}

Blog.objects.in_bulk(['beatles_blog'], field_name='slug')
{'beatles_blog': <Blog: Beatles Blog>}

如何在Django中获取用户IP地址?

问题:如何在Django中获取用户IP地址?

如何在Django中获取用户的IP?

我有这样的看法:

# Create your views
from django.contrib.gis.utils import GeoIP
from django.template import  RequestContext
from django.shortcuts import render_to_response


def home(request):
  g = GeoIP()
  client_ip = request.META['REMOTE_ADDR']
  lat,long = g.lat_lon(client_ip)
  return render_to_response('home_page_tmp.html',locals())

但是我得到这个错误:

KeyError at /mypage/
    'REMOTE_ADDR'
    Request Method: GET
    Request URL:    http://mywebsite.com/mypage/
    Django Version: 1.2.4
    Exception Type: KeyError
    Exception Value:    
    'REMOTE_ADDR'
    Exception Location: /mysite/homepage/views.py in home, line 9
    Python Executable:  /usr/bin/python
    Python Version: 2.6.6
    Python Path:    ['/mysite', '/usr/local/lib/python2.6/dist-packages/flup-1.0.2-py2.6.egg', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/lib-old', '/usr/lib/python2.6/lib-dynload', '/usr/local/lib/python2.6/dist-packages', '/usr/lib/python2.6/dist-packages', '/usr/lib/pymodules/python2.6']
    Server time:    Sun, 2 Jan 2011 20:42:50 -0600

How do I get user’s IP in django?

I have a view like this:

# Create your views
from django.contrib.gis.utils import GeoIP
from django.template import  RequestContext
from django.shortcuts import render_to_response


def home(request):
  g = GeoIP()
  client_ip = request.META['REMOTE_ADDR']
  lat,long = g.lat_lon(client_ip)
  return render_to_response('home_page_tmp.html',locals())

But I get this error:

KeyError at /mypage/
    'REMOTE_ADDR'
    Request Method: GET
    Request URL:    http://mywebsite.com/mypage/
    Django Version: 1.2.4
    Exception Type: KeyError
    Exception Value:    
    'REMOTE_ADDR'
    Exception Location: /mysite/homepage/views.py in home, line 9
    Python Executable:  /usr/bin/python
    Python Version: 2.6.6
    Python Path:    ['/mysite', '/usr/local/lib/python2.6/dist-packages/flup-1.0.2-py2.6.egg', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/lib-old', '/usr/lib/python2.6/lib-dynload', '/usr/local/lib/python2.6/dist-packages', '/usr/lib/python2.6/dist-packages', '/usr/lib/pymodules/python2.6']
    Server time:    Sun, 2 Jan 2011 20:42:50 -0600

回答 0

def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

确保正确配置了反向代理(如果有)(例如,mod_rpaf为Apache安装)。

注意:上面使用的第一X-Forwarded-For,但您可能要使用最后一项(例如,在Heroku的情况下:在Heroku上获取客户端的真实IP地址

然后将请求作为参数传递给它;

get_client_ip(request)
def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

Make sure you have reverse proxy (if any) configured correctly (e.g. mod_rpaf installed for Apache).

Note: the above uses the first item in X-Forwarded-For, but you might want to use the last item (e.g., in the case of Heroku: Get client’s real IP address on Heroku)

And then just pass the request as argument to it;

get_client_ip(request)

回答 1

您可以使用支持Python 23并处理IPv4IPv6的django-ipware

安装:

pip install django-ipware

简单用法:

# In a view or a middleware where the `request` object is available

from ipware import get_client_ip
ip, is_routable = get_client_ip(request)
if ip is None:
    # Unable to get the client's IP address
else:
    # We got the client's IP address
    if is_routable:
        # The client's IP address is publicly routable on the Internet
    else:
        # The client's IP address is private

# Order of precedence is (Public, Private, Loopback, None)

高级用法:

  • 自定义标头-ipware的自定义请求标头可以查看:

    i, r = get_client_ip(request, request_header_order=['X_FORWARDED_FOR'])
    i, r = get_client_ip(request, request_header_order=['X_FORWARDED_FOR', 'REMOTE_ADDR'])
  • 代理计数-Django服务器位于固定数量的代理之后:

    i, r = get_client_ip(request, proxy_count=1)
  • 受信任的代理-Django服务器位于一个或多个已知和受信任的代理之后:

    i, r = get_client_ip(request, proxy_trusted_ips=('177.2.2.2'))
    
    # For multiple proxies, simply add them to the list
    i, r = get_client_ip(request, proxy_trusted_ips=('177.2.2.2', '177.3.3.3'))
    
    # For proxies with fixed sub-domain and dynamic IP addresses, use partial pattern
    i, r = get_client_ip(request, proxy_trusted_ips=('177.2.', '177.3.'))

注意:请阅读此通知

You can use django-ipware which supports Python 2 & 3 and handles IPv4 & IPv6.

Install:

pip install django-ipware

Simple Usage:

# In a view or a middleware where the `request` object is available

from ipware import get_client_ip
ip, is_routable = get_client_ip(request)
if ip is None:
    # Unable to get the client's IP address
else:
    # We got the client's IP address
    if is_routable:
        # The client's IP address is publicly routable on the Internet
    else:
        # The client's IP address is private

# Order of precedence is (Public, Private, Loopback, None)

Advanced Usage:

  • Custom Header – Custom request header for ipware to look at:

    i, r = get_client_ip(request, request_header_order=['X_FORWARDED_FOR'])
    i, r = get_client_ip(request, request_header_order=['X_FORWARDED_FOR', 'REMOTE_ADDR'])
    
  • Proxy Count – Django server is behind a fixed number of proxies:

    i, r = get_client_ip(request, proxy_count=1)
    
  • Trusted Proxies – Django server is behind one or more known & trusted proxies:

    i, r = get_client_ip(request, proxy_trusted_ips=('177.2.2.2'))
    
    # For multiple proxies, simply add them to the list
    i, r = get_client_ip(request, proxy_trusted_ips=('177.2.2.2', '177.3.3.3'))
    
    # For proxies with fixed sub-domain and dynamic IP addresses, use partial pattern
    i, r = get_client_ip(request, proxy_trusted_ips=('177.2.', '177.3.'))
    

Note: read this notice.


回答 2

Alexander的回答很好,但是缺乏代理处理功能,这些代理有时会在HTTP_X_FORWARDED_FOR标头中返回多个IP。

真实IP通常位于列表的末尾,如此处所述:http : //en.wikipedia.org/wiki/X-Forwarded-For

该解决方案是对Alexander代码的简单修改:

def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[-1].strip()
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

Alexander’s answer is great, but lacks the handling of proxies that sometimes return multiple IP’s in the HTTP_X_FORWARDED_FOR header.

The real IP is usually at the end of the list, as explained here: http://en.wikipedia.org/wiki/X-Forwarded-For

The solution is a simple modification of Alexander’s code:

def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[-1].strip()
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

回答 3

我想提出对扬琴科答案的改进。

我不采用X_FORWARDED_FOR列表中的第一个IP,而是采用第一个不知道内部IP的IP,因为某些路由器不遵守该协议,您可以将内部IP视为列表的第一个值。

PRIVATE_IPS_PREFIX = ('10.', '172.', '192.', )

def get_client_ip(request):
    """get the client ip from the request
    """
    remote_address = request.META.get('REMOTE_ADDR')
    # set the default value of the ip to be the REMOTE_ADDR if available
    # else None
    ip = remote_address
    # try to get the first non-proxy ip (not a private ip) from the
    # HTTP_X_FORWARDED_FOR
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        proxies = x_forwarded_for.split(',')
        # remove the private ips from the beginning
        while (len(proxies) > 0 and
                proxies[0].startswith(PRIVATE_IPS_PREFIX)):
            proxies.pop(0)
        # take the first ip which is not a private one (of a proxy)
        if len(proxies) > 0:
            ip = proxies[0]

    return ip

希望这对遇到同样问题的Google同事有所帮助。

I would like to suggest an improvement to yanchenko’s answer.

Instead of taking the first ip in the X_FORWARDED_FOR list, I take the first one which in not a known internal ip, as some routers don’t respect the protocol, and you can see internal ips as the first value of the list.

PRIVATE_IPS_PREFIX = ('10.', '172.', '192.', )

def get_client_ip(request):
    """get the client ip from the request
    """
    remote_address = request.META.get('REMOTE_ADDR')
    # set the default value of the ip to be the REMOTE_ADDR if available
    # else None
    ip = remote_address
    # try to get the first non-proxy ip (not a private ip) from the
    # HTTP_X_FORWARDED_FOR
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        proxies = x_forwarded_for.split(',')
        # remove the private ips from the beginning
        while (len(proxies) > 0 and
                proxies[0].startswith(PRIVATE_IPS_PREFIX)):
            proxies.pop(0)
        # take the first ip which is not a private one (of a proxy)
        if len(proxies) > 0:
            ip = proxies[0]

    return ip

I hope this helps fellow Googlers who have the same problem.


回答 4

这是完成此任务的简短说明:

request.META.get('HTTP_X_FORWARDED_FOR', request.META.get('REMOTE_ADDR', '')).split(',')[0].strip()

here is a short one liner to accomplish this:

request.META.get('HTTP_X_FORWARDED_FOR', request.META.get('REMOTE_ADDR', '')).split(',')[0].strip()

回答 5

最简单的解决方案(如果您使用的是fastcgi + nignx)是itgorilla评论的内容:

谢谢您提出这个好问题。我的fastcgi没有传递REMOTE_ADDR元密钥。我在nginx.conf中添加了以下行,并修复了该问题:fastcgi_param REMOTE_ADDR $ remote_addr; – itgorilla

附:我添加这个答案只是为了使他的解决方案更明显。

The simpliest solution (in case you are using fastcgi+nignx) is what itgorilla commented:

Thank you for this great question. My fastcgi was not passing the REMOTE_ADDR meta key. I added the line below in the nginx.conf and fixed the problem: fastcgi_param REMOTE_ADDR $remote_addr; – itgorilla

Ps: I added this answer just to make his solution more visible.


回答 6

不再困惑在最新版本的Django中,明确提到客户端的Ip地址可从以下位置获得:

request.META.get("REMOTE_ADDR")

有关更多信息,请检查Django Docs

No More confusion In the recent versions of Django it is mentioned clearly that the Ip address of the client is available at

request.META.get("REMOTE_ADDR")

for more info check the Django Docs


回答 7

就我而言,上述方法均无效,因此我必须检查uwsgi+django源代码并在nginx中传递静态参数,并查看原因/方式,以下是我发现的内容。

环境信息:
python版本:2.7.5
Django版本:(1, 6, 6, 'final', 0)
nginx版本:nginx/1.6.0
uwsgi:2.0.7

环保设置信息:
nginx作为反向代理,在端口80 uwsgi处作为上游unix套接字侦听,最终将响应请求

Django配置信息:

USE_X_FORWARDED_HOST = True # with or without this line does not matter

Nginx的配置:

uwsgi_param      X-Real-IP              $remote_addr;
// uwsgi_param   X-Forwarded-For        $proxy_add_x_forwarded_for;
// uwsgi_param   HTTP_X_FORWARDED_FOR   $proxy_add_x_forwarded_for;

// hardcode for testing
uwsgi_param      X-Forwarded-For        "10.10.10.10";
uwsgi_param      HTTP_X_FORWARDED_FOR   "20.20.20.20";

在Django应用中获取所有参数:

X-Forwarded-For :       10.10.10.10
HTTP_X_FORWARDED_FOR :  20.20.20.20

结论:

因此,基本上,您必须在nginx中指定完全相同的字段/参数名称,并使用 request.META[field/param]在Django应用中。

现在,您可以决定是添加中间件(拦截器)还是仅HTTP_X_FORWARDED_FOR在某些视图中进行解析。

In my case none of above works, so I have to check uwsgi + django source code and pass static param in nginx and see why/how, and below is what I have found.

Env info:
python version: 2.7.5
Django version: (1, 6, 6, 'final', 0)
nginx version: nginx/1.6.0
uwsgi: 2.0.7

Env setting info:
nginx as reverse proxy listening at port 80 uwsgi as upstream unix socket, will response to the request eventually

Django config info:

USE_X_FORWARDED_HOST = True # with or without this line does not matter

nginx config:

uwsgi_param      X-Real-IP              $remote_addr;
// uwsgi_param   X-Forwarded-For        $proxy_add_x_forwarded_for;
// uwsgi_param   HTTP_X_FORWARDED_FOR   $proxy_add_x_forwarded_for;

// hardcode for testing
uwsgi_param      X-Forwarded-For        "10.10.10.10";
uwsgi_param      HTTP_X_FORWARDED_FOR   "20.20.20.20";

getting all the params in django app:

X-Forwarded-For :       10.10.10.10
HTTP_X_FORWARDED_FOR :  20.20.20.20

Conclusion:

So basically, you have to specify exactly the same field/param name in nginx, and use request.META[field/param] in django app.

And now you can decide whether to add a middleware (interceptor) or just parse HTTP_X_FORWARDED_FOR in certain views.


回答 8

最初从Django中删除功能的原因是最终无法信任标头。原因是容易欺骗。例如,建议的配置Nginx反向代理的方法是:

add_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header X-Real-Ip       $remote_addr;

当您这样做时:

curl -H 'X-Forwarded-For: 8.8.8.8, 192.168.1.2' http://192.168.1.3/

您在myhost.com中的nginx将继续发送:

X-Forwarded-For: 8.8.8.8, 192.168.1.2, 192.168.1.3

X-Real-IP如果您盲目按照说明进行操作它将是第一个先前的代理的IP。

如果信任您的用户是个问题,您可以尝试以下方法django-xffhttps : //pypi.python.org/pypi/django-xff/

The reason the functionality was removed from Django originally was that the header cannot ultimately be trusted. The reason is that it is easy to spoof. For example the recommended way to configure an nginx reverse proxy is to:

add_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header X-Real-Ip       $remote_addr;

When you do:

curl -H 'X-Forwarded-For: 8.8.8.8, 192.168.1.2' http://192.168.1.3/

Your nginx in myhost.com will send onwards:

X-Forwarded-For: 8.8.8.8, 192.168.1.2, 192.168.1.3

The X-Real-IP will be the IP of the first previous proxy if you follow the instructions blindly.

In case trusting who your users are is an issue, you could try something like django-xff: https://pypi.python.org/pypi/django-xff/


回答 9

我在上面的答案中也缺少代理。我get_ip_address_from_requestdjango_easy_timezones使用

from easy_timezones.utils import get_ip_address_from_request, is_valid_ip, is_local_ip
ip = get_ip_address_from_request(request)
try:
    if is_valid_ip(ip):
        geoip_record = IpRange.objects.by_ip(ip)
except IpRange.DoesNotExist:
    return None

这是method get_ip_address_from_request,IPv4和IPv6就绪的:

def get_ip_address_from_request(request):
    """ Makes the best attempt to get the client's real IP or return the loopback """
    PRIVATE_IPS_PREFIX = ('10.', '172.', '192.', '127.')
    ip_address = ''
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', '')
    if x_forwarded_for and ',' not in x_forwarded_for:
        if not x_forwarded_for.startswith(PRIVATE_IPS_PREFIX) and is_valid_ip(x_forwarded_for):
            ip_address = x_forwarded_for.strip()
    else:
        ips = [ip.strip() for ip in x_forwarded_for.split(',')]
        for ip in ips:
            if ip.startswith(PRIVATE_IPS_PREFIX):
                continue
            elif not is_valid_ip(ip):
                continue
            else:
                ip_address = ip
                break
    if not ip_address:
        x_real_ip = request.META.get('HTTP_X_REAL_IP', '')
        if x_real_ip:
            if not x_real_ip.startswith(PRIVATE_IPS_PREFIX) and is_valid_ip(x_real_ip):
                ip_address = x_real_ip.strip()
    if not ip_address:
        remote_addr = request.META.get('REMOTE_ADDR', '')
        if remote_addr:
            if not remote_addr.startswith(PRIVATE_IPS_PREFIX) and is_valid_ip(remote_addr):
                ip_address = remote_addr.strip()
    if not ip_address:
        ip_address = '127.0.0.1'
    return ip_address

I was also missing proxy in above answer. I used get_ip_address_from_request from django_easy_timezones.

from easy_timezones.utils import get_ip_address_from_request, is_valid_ip, is_local_ip
ip = get_ip_address_from_request(request)
try:
    if is_valid_ip(ip):
        geoip_record = IpRange.objects.by_ip(ip)
except IpRange.DoesNotExist:
    return None

And here is method get_ip_address_from_request, IPv4 and IPv6 ready:

def get_ip_address_from_request(request):
    """ Makes the best attempt to get the client's real IP or return the loopback """
    PRIVATE_IPS_PREFIX = ('10.', '172.', '192.', '127.')
    ip_address = ''
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', '')
    if x_forwarded_for and ',' not in x_forwarded_for:
        if not x_forwarded_for.startswith(PRIVATE_IPS_PREFIX) and is_valid_ip(x_forwarded_for):
            ip_address = x_forwarded_for.strip()
    else:
        ips = [ip.strip() for ip in x_forwarded_for.split(',')]
        for ip in ips:
            if ip.startswith(PRIVATE_IPS_PREFIX):
                continue
            elif not is_valid_ip(ip):
                continue
            else:
                ip_address = ip
                break
    if not ip_address:
        x_real_ip = request.META.get('HTTP_X_REAL_IP', '')
        if x_real_ip:
            if not x_real_ip.startswith(PRIVATE_IPS_PREFIX) and is_valid_ip(x_real_ip):
                ip_address = x_real_ip.strip()
    if not ip_address:
        remote_addr = request.META.get('REMOTE_ADDR', '')
        if remote_addr:
            if not remote_addr.startswith(PRIVATE_IPS_PREFIX) and is_valid_ip(remote_addr):
                ip_address = remote_addr.strip()
    if not ip_address:
        ip_address = '127.0.0.1'
    return ip_address

回答 10

在django.VERSION(2,1,1,’final’,0)请求处理程序中

sock=request._stream.stream.raw._sock
#<socket.socket fd=1236, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.1.111', 8000), raddr=('192.168.1.111', 64725)>
client_ip,port=sock.getpeername()

如果您两次调用上面的代码,您可能会得到

AttributeError(“’_ io.BytesIO’对象没有属性’stream’”,)

AttributeError(“’LimitedStream’对象没有属性’raw’”)

In django.VERSION (2, 1, 1, ‘final’, 0) request handler

sock=request._stream.stream.raw._sock
#<socket.socket fd=1236, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.1.111', 8000), raddr=('192.168.1.111', 64725)>
client_ip,port=sock.getpeername()

if you call above code twice,you may got

AttributeError(“‘_io.BytesIO’ object has no attribute ‘stream'”,)

AttributeError(“‘LimitedStream’ object has no attribute ‘raw'”)


如何将两个“唯一”字段定义为一对

问题:如何将两个“唯一”字段定义为一对

有没有一种方法可以将几个字段定义为Django中唯一的字段?

我有一张(期刊的)卷表,而我不希望同一期刊有一个以上的卷号。

class Volume(models.Model):
    id = models.AutoField(primary_key=True)
    journal_id = models.ForeignKey(Journals, db_column='jid', null=True, verbose_name = "Journal")
    volume_number = models.CharField('Volume Number', max_length=100)
    comments = models.TextField('Comments', max_length=4000, blank=True)

我试图将unique = Trueas属性放在字段中journal_idvolume_number但是不起作用。

Is there a way to define a couple of fields as unique in Django?

I have a table of volumes (of journals) and I don’t want more then one volume number for the same journal.

class Volume(models.Model):
    id = models.AutoField(primary_key=True)
    journal_id = models.ForeignKey(Journals, db_column='jid', null=True, verbose_name = "Journal")
    volume_number = models.CharField('Volume Number', max_length=100)
    comments = models.TextField('Comments', max_length=4000, blank=True)

I tried to put unique = True as attribute in the fields journal_id and volume_number but it doesn’t work.


回答 0

有一个简单的解决方案称为unique_together,它可以完全满足您的要求。

例如:

class MyModel(models.Model):
  field1 = models.CharField(max_length=50)
  field2 = models.CharField(max_length=50)

  class Meta:
    unique_together = ('field1', 'field2',)

在您的情况下:

class Volume(models.Model):
  id = models.AutoField(primary_key=True)
  journal_id = models.ForeignKey(Journals, db_column='jid', null=True, verbose_name = "Journal")
  volume_number = models.CharField('Volume Number', max_length=100)
  comments = models.TextField('Comments', max_length=4000, blank=True)

  class Meta:
    unique_together = ('journal_id', 'volume_number',)

There is a simple solution for you called unique_together which does exactly what you want.

For example:

class MyModel(models.Model):
  field1 = models.CharField(max_length=50)
  field2 = models.CharField(max_length=50)

  class Meta:
    unique_together = ('field1', 'field2',)

And in your case:

class Volume(models.Model):
  id = models.AutoField(primary_key=True)
  journal_id = models.ForeignKey(Journals, db_column='jid', null=True, verbose_name = "Journal")
  volume_number = models.CharField('Volume Number', max_length=100)
  comments = models.TextField('Comments', max_length=4000, blank=True)

  class Meta:
    unique_together = ('journal_id', 'volume_number',)

回答 1

Django 2.2以上

使用constraints功能UniqueConstraint优于unique_together

从Django文档中获得unique_together

改用UniqueConstraint和Constraints选项。
UniqueConstraint提供的功能比unique_together还要多。
将来可能不推荐使用unique_together。

例如:

class Volume(models.Model):
    id = models.AutoField(primary_key=True)
    journal_id = models.ForeignKey(Journals, db_column='jid', null=True, verbose_name="Journal")
    volume_number = models.CharField('Volume Number', max_length=100)
    comments = models.TextField('Comments', max_length=4000, blank=True)

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['journal_id', 'volume_number'], name='name of constraint')
        ]

Django 2.2+

Using the constraints features UniqueConstraint is preferred over unique_together.

From the Django documentation for unique_together:

Use UniqueConstraint with the constraints option instead.
UniqueConstraint provides more functionality than unique_together.
unique_together may be deprecated in the future.

For example:

class Volume(models.Model):
    id = models.AutoField(primary_key=True)
    journal_id = models.ForeignKey(Journals, db_column='jid', null=True, verbose_name="Journal")
    volume_number = models.CharField('Volume Number', max_length=100)
    comments = models.TextField('Comments', max_length=4000, blank=True)

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['journal_id', 'volume_number'], name='name of constraint')
        ]

on_delete对Django模型有什么作用?

问题:on_delete对Django模型有什么作用?

我对Django非常熟悉,但是最近发现on_delete=models.CASCADE模型中存在一个选项,我在文档中搜索了相同的选项,但找不到以下内容:

在Django 1.9中进行了更改:

on_delete现在可以用作第二个位置参数(以前通常只作为关键字参数传递)。在Django 2.0中,这是必填参数。

使用的一个例子是

from django.db import models

class Car(models.Model):
    manufacturer = models.ForeignKey(
        'Manufacturer',
        on_delete=models.CASCADE,
    )
    # ...

class Manufacturer(models.Model):
    # ...
    pass

on_delete是做什么的?(我想如果删除模型,要执行的操作

怎么models.CASCADE办?(文档中的任何提示

还有其他可用的选项(如果我的猜测是正确的)?

有关此文档的位置在哪里?

I’m quite familiar with Django, but recently noticed there exists an on_delete=models.CASCADE option with the models, I have searched for the documentation for the same but couldn’t find anything more than:

Changed in Django 1.9:

on_delete can now be used as the second positional argument (previously it was typically only passed as a keyword argument). It will be a required argument in Django 2.0.

an example case of usage is

from django.db import models

class Car(models.Model):
    manufacturer = models.ForeignKey(
        'Manufacturer',
        on_delete=models.CASCADE,
    )
    # ...

class Manufacturer(models.Model):
    # ...
    pass

What does on_delete do? (I guess the actions to be done if the model is deleted)

What does models.CASCADE do? (any hints in documentation)

What other options are available (if my guess is correct)?

Where does the documentation for this reside?


回答 0

这是删除引用对象时采取的行为。它不是特定于Django的,这是一种SQL标准。

发生此类事件时,有6种可能的操作:

  • CASCADE:删除引用的对象时,还请删除引用了该对象的对象(例如,删除博客文章时,您可能还希望删除注释)。SQL等效项:CASCADE
  • PROTECT:禁止删除引用的对象。要删除它,您将必须删除所有手动引用它的对象。SQL等效项:RESTRICT
  • SET_NULL:将引用设置为NULL(要求该字段可为空)。例如,当删除用户时,您可能希望保留他在博客文章中发布的评论,但说该评论是由匿名(或已删除)用户发布的。SQL等效项:SET NULL
  • SET_DEFAULT:设置默认值。SQL等效项:SET DEFAULT
  • SET(...):设置给定值。这不是SQL标准的一部分,完全由Django处理。
  • DO_NOTHING:这可能是一个非常糟糕的主意,因为这会在数据库中造成完整性问题(引用实际上不存在的对象)。SQL等效项:NO ACTION

资料来源:Django说明文件

例如,另请参阅PostGreSQL文档

在大多数情况下,这CASCADE是预期的行为,但是对于每个ForeignKey,您应始终问自己在这种情况下的预期行为是什么。PROTECT并且SET_NULL经常有用。设置CASCADE不应该设置的位置,可以通过简单地删除单个用户来级联删除所有数据库。


附加说明以阐明级联方向

有趣的是,注意到CASCADE行动的方向对于许多人来说并不明确。事实上,这很有趣地看到,只有CASCADE行动并不清楚。我知道级联行为可能会造成混淆,但是您必须认为它与任何其他动作是同一方向。因此,如果您觉得自己CASCADE不清楚方向,那实际上意味着on_delete您不清楚自己的行为。

在您的数据库中,外键基本上由一个整数字段表示,该字段的值是外对象的主键。假设您有一个comment_A条目,它具有一个article_B条目的外键。如果您删除条目comment_A,那么一切都很好,article_B以前可以不带有comment_A生存,并且也不会被删除。但是,如果删除article_B,则comment_A会慌!它永远都离不开article_B并需要它,它是它属性的一部分(article=article_B,但是* article_B ** ???)。这是on_delete确定如何解决此完整性错误的步骤,或者说:

  • “不!请!不要!我不能没有你!” PROTECT用SQL语言表示)
  • “好吧,如果我不是你的,那我就不是任何人的”(说SET_NULL
  • “再见,我不能没有article_B生活”自杀(这是CASCADE行为)。
  • “没关系,我有多余的恋人,从现在开始我将引用article_C”SET_DEFAULT,甚至SET(...))。
  • “我不能面对现实,即使那是我唯一的事情,我也会继续给你起名字!” DO_NOTHING

我希望它使级联方向更清晰。:)

This is the behaviour to adopt when the referenced object is deleted. It is not specific to django, this is an SQL standard.

There are 6 possible actions to take when such event occurs:

  • CASCADE: When the referenced object is deleted, also delete the objects that have references to it (When you remove a blog post for instance, you might want to delete comments as well). SQL equivalent: CASCADE.
  • PROTECT: Forbid the deletion of the referenced object. To delete it you will have to delete all objects that reference it manually. SQL equivalent: RESTRICT.
  • SET_NULL: Set the reference to NULL (requires the field to be nullable). For instance, when you delete a User, you might want to keep the comments he posted on blog posts, but say it was posted by an anonymous (or deleted) user. SQL equivalent: SET NULL.
  • SET_DEFAULT: Set the default value. SQL equivalent: SET DEFAULT.
  • SET(...): Set a given value. This one is not part of the SQL standard and is entirely handled by Django.
  • DO_NOTHING: Probably a very bad idea since this would create integrity issues in your database (referencing an object that actually doesn’t exist). SQL equivalent: NO ACTION.

Source: Django documentation

See also the documentation of PostGreSQL for instance.

In most cases, CASCADE is the expected behaviour, but for every ForeignKey, you should always ask yourself what is the expected behaviour in this situation. PROTECT and SET_NULL are often useful. Setting CASCADE where it should not, can potentially delete all your database in cascade, by simply deleting a single user.


Additional note to clarify cascade direction

It’s funny to notice that the direction of the CASCADE action is not clear to many people. Actually, it’s funny to notice that only the CASCADE action is not clear. I understand the cascade behavior might be confusing, however you must think that it is the same direction as any other action. Thus, if you feel that CASCADE direction is not clear to you, it actually means that on_delete behavior is not clear to you.

In your database, a foreign key is basically represented by an integer field which value is the primary key of the foreign object. Let’s say you have an entry comment_A, which has a foreign key to an entry article_B. If you delete the entry comment_A, everything is fine, article_B used to live without comment_A and don’t bother if it’s deleted. However, if you delete article_B, then comment_A panics! It never lived without article_B and needs it, it’s part of its attributes (article=article_B, but what is *article_B**???). This is where on_delete steps in, to determine how to resolve this integrity error, either by saying:

  • “No! Please! Don’t! I can’t live without you!” (which is said PROTECT in SQL language)
  • “Alright, if I’m not yours, then I’m nobody’s” (which is said SET_NULL)
  • “Good bye world, I can’t live without article_B” and commit suicide (this is the CASCADE behavior).
  • “It’s OK, I’ve got spare lover, I’ll reference article_C from now” (SET_DEFAULT, or even SET(...)).
  • “I can’t face reality, I’ll keep calling your name even if that’s the only thing left to me!” (DO_NOTHING)

I hope it makes cascade direction clearer. :)


回答 1

on_delete方法用于告诉Django如何处理依赖于您删除的模型实例的模型实例。(例如,ForeignKey恋爱关系)。该命令on_delete=models.CASCADE告诉Django级联删除效果,即也继续删除相关模型。

这是一个更具体的例子。假设您有一个Author模型ForeignKey中的一个Book模型。现在,如果删除Author模型实例,则Django将不知道如何处理Book依赖于该Author模型实例的模型实例。该on_delete方法告诉Django在这种情况下该怎么做。设置on_delete=models.CASCADE将指示Django级联删除效果,即删除所有Book依赖于Author您删除的模型实例的模型实例。

注意:on_delete在Django 2.0中将成为必填参数。在旧版本中,默认为CASCADE

这是完整的官方文档。

The on_delete method is used to tell Django what to do with model instances that depend on the model instance you delete. (e.g. a ForeignKey relationship). The on_delete=models.CASCADE tells Django to cascade the deleting effect i.e. continue deleting the dependent models as well.

Here’s a more concrete example. Assume you have an Author model that is a ForeignKey in a Book model. Now, if you delete an instance of the Author model, Django would not know what to do with instances of the Book model that depend on that instance of Author model. The on_delete method tells Django what to do in that case. Setting on_delete=models.CASCADE will instruct Django to cascade the deleting effect i.e. delete all the Book model instances that depend on the Author model instance you deleted.

Note: on_delete will become a required argument in Django 2.0. In older versions it defaults to CASCADE.

Here’s the entire official documentation.


回答 2

仅供参考,on_delete模型中的参数从听起来像是倒过来的。您on_delete在模型上放置了外键(FK),以告诉django如果删除了记录中指向的FK条目该怎么办。选项我们店已经使用的大多是PROTECTCASCADESET_NULL。这是我弄清楚的基本规则:

  1. 使用PROTECT时,你的FK指向一个查表真的不应该被改变,并且肯定不会引起你的表来改变。如果有人试图删除该查询表上的条目,则PROTECT防止该条目与任何记录绑定时删除该条目。它还可以防止从删除的Django 你的记录,只是因为它删除了一个查找表中的条目。最后一部分至关重要。 如果有人要从“性别”表中删除性别“女性”,我肯定不希望立即删除我在“人”表中拥有该性别的任何人。
  2. 使用CASCADE时,你的FK指向“父”的纪录。所以,如果一个人可以有很多PersonEthnicity项(他/她可以是美洲印第安人,黑色和白色),而那个人删除了,我真的想什么“孩子” PersonEthnicity条目被删除。没有人,他们是无关紧要的。
  3. 使用SET_NULL时,你希望人们被允许删除查找表中的条目,但你仍然要保留记录。例如,如果某人可以拥有一所高中,但对我而言,那所高中不在我的查询表上并不重要on_delete=SET_NULL。这会将我的“个人”记录保留在那里;只会将“我的人”上的高中FK设置为​​null。显然,您必须允许null=True该FK。

这是一个可以完成所有三件事的模型示例:

class PurchPurchaseAccount(models.Model):
    id = models.AutoField(primary_key=True)
    purchase = models.ForeignKey(PurchPurchase, null=True, db_column='purchase', blank=True, on_delete=models.CASCADE) # If "parent" rec gone, delete "child" rec!!!
    paid_from_acct = models.ForeignKey(PurchPaidFromAcct, null=True, db_column='paid_from_acct', blank=True, on_delete=models.PROTECT) # Disallow lookup deletion & do not delete this rec.
    _updated = models.DateTimeField()
    _updatedby = models.ForeignKey(Person, null=True, db_column='_updatedby', blank=True, related_name='acctupdated_by', on_delete=models.SET_NULL) # Person records shouldn't be deleted, but if they are, preserve this PurchPurchaseAccount entry, and just set this person to null.

    def __unicode__(self):
        return str(self.paid_from_acct.display)
    class Meta:
        db_table = u'purch_purchase_account'

作为最后一个提示,您是否知道如果指定on_delete(或未指定),默认行为是CASCADE?这意味着,如果有人删除了您“性别”表上的性别条目,则具有该性别的任何“人”记录也将被删除!

我会说:“如果有疑问,那就出发on_delete=models.PROTECT。” 然后测试您的应用程序。您将快速找出哪些FK应该标记为其他值,而不会危及您的任何数据。

另外,值得注意的on_delete=CASCADE是,如果这是您选择的行为,实际上并没有添加到您的任何迁移中。我猜这是因为它是默认设置,所以放置on_delete=CASCADE和放置任何东西都是一样的。

FYI, the on_delete parameter in models is backwards from what it sounds like. You put on_delete on a Foreign Key (FK) on a model to tell django what to do if the FK entry that you are pointing to on your record is deleted. The options our shop have used the most are PROTECT, CASCADE, and SET_NULL. Here are the basic rules I have figured out:

  1. Use PROTECT when your FK is pointing to a look-up table that really shouldn’t be changing and that certainly should not cause your table to change. If anyone tries to delete an entry on that look-up table, PROTECT prevents them from deleting it if it is tied to any records. It also prevents django from deleting your record just because it deleted an entry on a look-up table. This last part is critical. If someone were to delete the gender “Female” from my Gender table, I CERTAINLY would NOT want that to instantly delete any and all people I had in my Person table who had that gender.
  2. Use CASCADE when your FK is pointing to a “parent” record. So, if a Person can have many PersonEthnicity entries (he/she can be American Indian, Black, and White), and that Person is deleted, I really would want any “child” PersonEthnicity entries to be deleted. They are irrelevant without the Person.
  3. Use SET_NULL when you do want people to be allowed to delete an entry on a look-up table, but you still want to preserve your record. For example, if a Person can have a HighSchool, but it doesn’t really matter to me if that high-school goes away on my look-up table, I would say on_delete=SET_NULL. This would leave my Person record out there; it just would just set the high-school FK on my Person to null. Obviously, you will have to allow null=True on that FK.

Here is an example of a model that does all three things:

class PurchPurchaseAccount(models.Model):
    id = models.AutoField(primary_key=True)
    purchase = models.ForeignKey(PurchPurchase, null=True, db_column='purchase', blank=True, on_delete=models.CASCADE) # If "parent" rec gone, delete "child" rec!!!
    paid_from_acct = models.ForeignKey(PurchPaidFromAcct, null=True, db_column='paid_from_acct', blank=True, on_delete=models.PROTECT) # Disallow lookup deletion & do not delete this rec.
    _updated = models.DateTimeField()
    _updatedby = models.ForeignKey(Person, null=True, db_column='_updatedby', blank=True, related_name='acctupdated_by', on_delete=models.SET_NULL) # Person records shouldn't be deleted, but if they are, preserve this PurchPurchaseAccount entry, and just set this person to null.

    def __unicode__(self):
        return str(self.paid_from_acct.display)
    class Meta:
        db_table = u'purch_purchase_account'

As a last tidbit, did you know that if you don’t specify on_delete (or didn’t), the default behavior is CASCADE? This means that if someone deleted a gender entry on your Gender table, any Person records with that gender were also deleted!

I would say, “If in doubt, set on_delete=models.PROTECT.” Then go test your application. You will quickly figure out which FKs should be labeled the other values without endangering any of your data.

Also, it is worth noting that on_delete=CASCADE is actually not added to any of your migrations, if that is the behavior you are selecting. I guess this is because it is the default, so putting on_delete=CASCADE is the same thing as putting nothing.


回答 3

如前所述,CASCADE将删除具有外键的记录,并引用另一个已删除的对象。因此,例如,如果您有一个房地产网站,并且有一个引用城市的房地产

class City(models.Model):
    # define model fields for a city

class Property(models.Model):
    city = models.ForeignKey(City, on_delete = models.CASCADE)
    # define model fields for a property

现在,当从数据库中删除城市时,所有关联的属性(例如,位于该城市的房地产)也将从数据库中删除

现在,我还要提及其他选项的优点,例如SET_NULL或SET_DEFAULT甚至DO_NOTHING。基本上,从管理角度来看,您要“删除”这些记录。但是您真的不希望它们消失。因为许多的原因。可能有人不小心删除了该文件,或者进行了审核和监视。和简单的报告。因此,这可能是一种将财产与城市“断开连接”的方式。同样,这将取决于您的应用程序的编写方式。

例如,某些应用程序的“已删除”字段为0或1。所有搜索和列表视图等内容,可能出现在报表中或用户可以从前端访问它的任何位置,均不包括deleted == 1。但是,如果您创建自定义报告或自定义查询来下拉已删除记录的列表,甚至更多,以便查看上次修改的时间(另一个字段)以及由谁(即谁删除它和何时删除)。从行政角度来看,这是非常有利的。

并且不要忘记,您可以像还原deleted = 0那些记录一样简单地还原意外删除。

我的观点是,如果有功能,总会有其背后的原因。并非总是一个很好的理由。但这是一个原因。往往也是一个好人。

As mentioned earlier, CASCADE will delete the record that has a foreign key and references another object that was deleted. So for example if you have a real estate website and have a Property that references a City

class City(models.Model):
    # define model fields for a city

class Property(models.Model):
    city = models.ForeignKey(City, on_delete = models.CASCADE)
    # define model fields for a property

and now when the City is deleted from the database, all associated Properties (eg. real estate located in that city) will also be deleted from the database

Now I also want to mention the merit of other options, such as SET_NULL or SET_DEFAULT or even DO_NOTHING. Basically, from the administration perspective, you want to “delete” those records. But you don’t really want them to disappear. For many reasons. Someone might have deleted it accidentally, or for auditing and monitoring. And plain reporting. So it can be a way to “disconnect” the property from a City. Again, it will depend on how your application is written.

For example, some applications have a field “deleted” which is 0 or 1. And all their searches and list views etc, anything that can appear in reports or anywhere the user can access it from the front end, exclude anything that is deleted == 1. However, if you create a custom report or a custom query to pull down a list of records that were deleted and even more so to see when it was last modified (another field) and by whom (i.e. who deleted it and when)..that is very advantageous from the executive standpoint.

And don’t forget that you can revert accidental deletions as simple as deleted = 0 for those records.

My point is, if there is a functionality, there is always a reason behind it. Not always a good reason. But a reason. And often a good one too.


回答 4

这是您的问题答案:为什么我们使用on_delete?

删除由ForeignKey引用的对象时,默认情况下,Django会模拟SQL约束ON DELETE CASCADE的行为,并删除包含ForeignKey的对象。通过指定on_delete参数可以覆盖此行为。例如,如果您具有可为空的ForeignKey,并且希望在删除引用的对象时将其设置为null:

user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)

on_delete的可能值在django.db.models中找到:

级联级联删除;默认值。

保护:通过引发ProtectedError(django.db.IntegrityError的子类)来防止删除引用的对象。

SET_NULL:将ForeignKey设置为null;否则为false。仅当null为True时才有可能。

SET_DEFAULT:将ForeignKey设置为其默认值;必须为ForeignKey设置默认值。

Here is answer for your question that says: why we use on_delete?

When an object referenced by a ForeignKey is deleted, Django by default emulates the behavior of the SQL constraint ON DELETE CASCADE and also deletes the object containing the ForeignKey. This behavior can be overridden by specifying the on_delete argument. For example, if you have a nullable ForeignKey and you want it to be set null when the referenced object is deleted:

user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)

The possible values for on_delete are found in django.db.models:

CASCADE: Cascade deletes; the default.

PROTECT: Prevent deletion of the referenced object by raising ProtectedError, a subclass of django.db.IntegrityError.

SET_NULL: Set the ForeignKey null; this is only possible if null is True.

SET_DEFAULT: Set the ForeignKey to its default value; a default for the ForeignKey must be set.


回答 5

假设您有两种模型,一种名为Person,另一种名为Companies

根据定义,一个人可以创建多个公司。

考虑到一个公司只能有一个人,因此我们希望在删除一个人时也删除与该人关联的所有公司。

因此,我们首先创建一个Person模型,像这样

class Person(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.id+self.name

然后,公司模型如下所示

class Companies(models.Model):
    title = models.CharField(max_length=20)
    description=models.CharField(max_length=10)
    person= models.ForeignKey(Person,related_name='persons',on_delete=models.CASCADE)

注意on_delete=models.CASCADE模型公司中的用法。也就是删除拥有它的人(Person类的实例)时删除所有公司。

Let’s say you have two models, one named Person and another one named Companies.

By definition, one person can create more than one company.

Considering a company can have one and only one person, we want that when a person is deleted that all the companies associated with that person also be deleted.

So, we start by creating a Person model, like this

class Person(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.id+self.name

Then, the Companies model can look like this

class Companies(models.Model):
    title = models.CharField(max_length=20)
    description=models.CharField(max_length=10)
    person= models.ForeignKey(Person,related_name='persons',on_delete=models.CASCADE)

Notice the usage of on_delete=models.CASCADE in the model Companies. That is to delete all companies when the person that owns it (instance of class Person) is deleted.


回答 6

通过考虑将FK添加到已存在的级联(即瀑布)中来重新定向“ CASCADE”功能的思维模型。该瀑布的来源是主键。删除流向下。

因此,如果将FK的on_delete定义为“ CASCADE”,则需要将此FK的记录添加到源自PK的一系列删除中。FK的记录是否可以参与此级联(“ SET_NULL”)。实际上,带有FK的记录甚至可能阻止删除流程!用“保护”建造一个水坝。

Re-orient your mental model of the functionality of “CASCADE” by thinking of adding a FK to an already existing cascade (i.e. a waterfall). The source of this waterfall is a Primary Key. Deletes flow down.

So if you define a FK’s on_delete as “CASCADE,” you’re adding this FK’s record to a cascade of deletes originating from the PK. The FK’s record may participate in this cascade or not (“SET_NULL”). In fact, a record with a FK may even prevent the flow of the deletes! Build a dam with “PROTECT.”


回答 7

使用CASCADE意味着实际上告诉Django删除引用的记录。在下面的民意调查应用示例中:当“问题”被删除时,它还将删除该问题具有的选择。

例如:问题:您如何得知我们的?(选择:1.朋友2.电视广告3.搜索引擎4.电子邮件促销)

删除此问题时,它还将从表中删除所有这四个选项。 请注意它流动的方向。您不必放置on_delete = models。问题模型中的CASCADE将其放置在Choice中。

from django.db import models



class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.dateTimeField('date_published')

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_legth=200)
    votes = models.IntegerField(default=0)

Using CASCADE means actually telling Django to delete the referenced record. In the poll app example below: When a ‘Question’ gets deleted it will also delete the Choices this Question has.

e.g Question: How did you hear about us? (Choices: 1. Friends 2. TV Ad 3. Search Engine 4. Email Promotion)

When you delete this question, it will also delete all these four choices from the table. Note that which direction it flows. You don’t have to put on_delete=models.CASCADE in Question Model put it in the Choice.

from django.db import models



class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.dateTimeField('date_published')

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_legth=200)
    votes = models.IntegerField(default=0)

‘pip’不被识别为内部或外部命令

问题:’pip’不被识别为内部或外部命令

尝试在计算机上安装Django时遇到奇怪的错误。

这是我在命令行中键入的序列:

C:\Python34>python get-pip.py
Requirement already up-to-date: pip in c:\python34\lib\site-packages
Cleaning up...

C:\Python34>pip install Django
'pip' is not recognized as an internal or external command,
operable program or batch file.

C:\Python34>lib\site-packages\pip install Django
'lib\site-packages\pip' is not recognized as an internal or external command,
operable program or batch file. 

是什么原因造成的?

编辑_______________________

根据要求,这是我输入echo%PATH%时得到的结果

C:\Python34>echo %PATH%
C:\Program Files\ImageMagick-6.8.8-Q16;C:\Program Files (x86)\Intel\iCLS Client\
;C:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\S
ystem32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\
Windows Live\Shared;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Progr
am Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Program Files\Intel\Intel(R) Mana
gement Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine C
omponents\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components
\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\P
rogram Files (x86)\nodejs\;C:\Program Files (x86)\Heroku\bin;C:\Program Files (x
86)\git\cmd;C:\RailsInstaller\Ruby2.0.0\bin;C:\RailsInstaller\Git\cmd;C:\RailsIn
staller\Ruby1.9.3\bin;C:\Users\Javi\AppData\Roaming\npm

I’m running into a weird error when trying to install Django on my computer.

This is the sequence that I typed into my command line:

C:\Python34>python get-pip.py
Requirement already up-to-date: pip in c:\python34\lib\site-packages
Cleaning up...

C:\Python34>pip install Django
'pip' is not recognized as an internal or external command,
operable program or batch file.

C:\Python34>lib\site-packages\pip install Django
'lib\site-packages\pip' is not recognized as an internal or external command,
operable program or batch file. 

What could be causing this?

EDIT _______________________

As requested this is what I get when I type in echo %PATH%

C:\Python34>echo %PATH%
C:\Program Files\ImageMagick-6.8.8-Q16;C:\Program Files (x86)\Intel\iCLS Client\
;C:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\S
ystem32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\
Windows Live\Shared;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Progr
am Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Program Files\Intel\Intel(R) Mana
gement Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine C
omponents\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components
\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\P
rogram Files (x86)\nodejs\;C:\Program Files (x86)\Heroku\bin;C:\Program Files (x
86)\git\cmd;C:\RailsInstaller\Ruby2.0.0\bin;C:\RailsInstaller\Git\cmd;C:\RailsIn
staller\Ruby1.9.3\bin;C:\Users\Javi\AppData\Roaming\npm

回答 0

您需要将pip安装的路径添加到PATH系统变量中。默认情况下,pip已安装C:\Python34\Scripts\pip(pip现在与python的新版本捆绑在一起),因此需要将路径“ C:\ Python34 \ Scripts”添加到PATH变量中。

要检查它是否已经在PATH变量中,请echo %PATH%在CMD提示符下键入

要将pip安装的路径添加到PATH变量中,可以使用“控制面板”或setx命令。例如:

setx PATH "%PATH%;C:\Python34\Scripts"

注意:根据官方文档,“使用setx变量设置的[v]变量仅在以后的命令窗口中可用,而在当前命令窗口中不可用”。特别是,输入上述命令后,您将需要启动一个新的cmd.exe实例,以利用新的环境变量。

感谢Scott Bartell指出这一点。

You need to add the path of your pip installation to your PATH system variable. By default, pip is installed to C:\Python34\Scripts\pip (pip now comes bundled with new versions of python), so the path “C:\Python34\Scripts” needs to be added to your PATH variable.

To check if it is already in your PATH variable, type echo %PATH% at the CMD prompt

To add the path of your pip installation to your PATH variable, you can use the Control Panel or the setx command. For example:

setx PATH "%PATH%;C:\Python34\Scripts"

Note: According to the official documentation, “[v]ariables set with setx variables are available in future command windows only, not in the current command window”. In particular, you will need to start a new cmd.exe instance after entering the above command in order to utilize the new environment variable.

Thanks to Scott Bartell for pointing this out.


回答 1

对于Windows,在安装软件包时,键入:

python -m pip install [packagename]

For windows when you install a package you type:

python -m pip install [packagename]

回答 2

对我而言:

set PATH=%PATH%;C:\Python34\Scripts

立即工作(尝试echo%PATH%之后,您将看到路径值为C:\ Python34 \ Scripts)。

感谢:https : //stackoverflow.com/a/9546345/1766166

For me command:

set PATH=%PATH%;C:\Python34\Scripts

worked immediately (try after echo %PATH% and you will see that your path has the value C:\Python34\Scripts).

Thanks to: https://stackoverflow.com/a/9546345/1766166


回答 3

到目前为止,在3.7.3版中,获取正确的系统变量存在一点问题。

尝试这个:

  1. 在cmd中输入“ start%appdata%”。

  2. 之后,该文件浏览器应在“ ../AppData/Roaming”中弹出。

返回一个目录,然后导航到“本地/程序/ Python / Python37-32 /脚本”。

注意:版本号可能会有所不同,因此,如果您复制并粘贴上述文件路径,它将无法正常工作。

完成此操作后,您现在具有已下载Python的正确位置。通过在地址栏中选择整个目录来复制文件路径。

完成此操作后,单击开始图标,然后导航到“控制面板”>“系统和安全性”>“系统”。然后单击面板左侧的“高级系统设置”。

单击右下角的环境变量后,将有两个框,一个上框和一个下框。在上方的框中:单击“路径”变量,然后单击右侧的“编辑”。单击“新建”,然后粘贴目录路径。它看起来应该像这样:

单击确定三次,打开cmd的新窗口,然后键入:pip。看看是否可行。

祝好运!

As of now, version 3.7.3 I had a little bit of an issue with getting the right system variable.

Try this:

  1. Type ‘start %appdata%’ in cmd.

  2. After that file explorer should pop up in ‘../AppData/Roaming’.

Go back one directory and navigate to ‘Local/Programs/Python/Python37-32/Scripts’.

NOTE: The version number may be different so if you copy and paste the above file path it could not work.

After you do this you now have the correct location of your downloaded Python. Copy your file path by selecting the whole directory in the address bar.

Once you do that click the start icon and navigate to the Control Panel > System and Security > System. Then click “Advanced System Settings” on the left side of the panel.

Once there click environment Variables on the bottom right and there will be two boxes, an upper and a lower box. In the upper box: Click on the ‘Path’ Variable and click ‘edit’ located on the right. Click ‘New’ and paste your directory Path. It should look something like this:

Click Ok three times, open a NEW window of cmd and type: pip. See if it works.

Good Luck!


回答 4

替代方式。

如果您不想添加PATH(如先前的书面回答所指出的那样),

但是您想执行pip作为命令,则可以使用py -m前缀做。

鉴于您必须一次又一次地执行此操作。

例如。

py -m <command>

py -m pip install --upgrade pip setuptools

另外,还要确保有pippy安装

Alternate way.

If you don’t want to add the PATH as the previous well written answers pointed out,

but you want to execute pip as your command then you can do that with py -m as prefix.

Given that you have to do it again and again.

eg.

py -m <command>

as in

py -m pip install --upgrade pip setuptools

Also make sure to have pip and py installed


回答 5

同样,长方法-在尝试了上述所有项目之后,这是最后的选择:

c:\python27\scripts\pip.exe install [package].whl

cd在车轮所在目录中之后

also, the long method – it was a last resort after trying all items above:

c:\python27\scripts\pip.exe install [package].whl

this after cd in directory where the wheel is located


回答 6

根据Python 3.6文档

默认情况下,可能未安装pip。一种可能的解决方法是:

python -m ensurepip --default-pip

As per Python 3.6 Documentation

It is possible that pip does not get installed by default. One potential fix is:

python -m ensurepip --default-pip

回答 7

转到控制面板>>卸载 更改程序,然后双击Python XXX修改安装。确保已检查并安装了PIP组件。

Go to control Panel >> Uninstall or change Program and double click on Python XXX to modify install. Make sure PIP component is checked and install.


回答 8

我意识到这是一个古老的问题,但是我刚才也遇到了同样的问题。将正确的文件夹(C:\Python33\Scripts)添加到路径后,我仍然无法pip运行。它只需要运行pip.exe install -package-而不是 运行 pip install -package-。只是一个想法。

I realize this is an old question, but I was having the same problem just now. After adding the proper folder (C:\Python33\Scripts) to the path, I still could not get pip to run. All it took was running pip.exe install -package- instead of pip install -package-. Just a thought.


回答 9

设置路径= %PATH%;C:\Python34\;C:\Python27\Scripts

set Path = %PATH%;C:\Python34\;C:\Python27\Scripts
Source


回答 10

控制面板->添加/删除程序-> Python->修改->可选功能(您可以单击所有内容),然后按下一步->选中“将python添加到环境变量”->安装

这应该可以解决您的路径问题,因此请跳至命令提示符,您现在可以使用pip。

Control Panel -> add/remove programs -> Python -> Modify -> optional Features (you can click everything) then press next -> Check “Add python to environment variables” -> Install

And that should solve your path issues, so jump to command prompt and you can use pip now.


回答 11

尝试进入Windows powershell或cmd提示符并输入:

python -m pip install openpyxl

Try going to windows powershell or cmd prompt and typing:

python -m pip install openpyxl


回答 12

在最新版本的python 3.6.2及更高版本中,提供了

C:\ Program Files(x86)\ Python36-32 \ Scripts

您可以将路径添加到我们的环境变量路径,如下所示

设置路径后,请确保关闭命令提示符或git。还应该在管理员模式下打开命令提示符。这是Windows 10的示例。

In latest version python 3.6.2 and above, is available in

C:\Program Files (x86)\Python36-32\Scripts

You can add the path to our environment variable path as below

Make sure you close your command prompt or git after setting up your path. Also should you open your command prompt in administrator mode. This is example for windows 10.


回答 13

甚至我都不熟悉,但是C:\ Python34 \ Scripts> pip install django为我工作。路径应设置为Python安装的Script文件夹所在的位置,即C:\ Python34 \ Scripts。我想这是因为django是一个基于python的框架,这就是为什么在安装时必须维护此目录结构的原因。

Even I’m new to this but, C:\Python34\Scripts>pip install django ,worked for me. The path should be set as where the Script folder of Python installation is i.e.C:\Python34\Scripts. I suppose its because django is a framework which is based on python that’s why this directory structure has to be maintained while installing.


回答 14

您可以尝试pip3,例如:

C:> pip3 install pandas

Yo can try pip3, something like:

C:> pip3 install pandas

回答 15

我刚刚安装了python 3.6.2。

我知道了

C:\ Users \ USERNAME \ AppData \ Local \ Programs \ Python \ Python36-32 \ Scripts

I have just installed python 3.6.2.

I got the path as

C:\Users\USERNAME\AppData\Local\Programs\Python\Python36-32\Scripts


回答 16

在Windows中,打开cmd并使用来找到PYTHON_HOME的位置where python,现在使用以下命令将该位置 添加到您的环境PATH中:

set PATH=%PATH%;<PYTHON_HOME>\Scripts

参考此


在Linux中,打开终端并使用来找到PYTHON_HOME的位置which python,现在使用来将其添加PYTHON_HOME/Scripts到PATH变量中:

PATH=$PATH:<PYTHON_HOME>\Scripts
export PATH

In Windows, open cmd and find the location of PYTHON_HOME using where python, now add this location to your Environment PATH using:

set PATH=%PATH%;<PYTHON_HOME>\Scripts

or Refer this


In Linux, open terminal and find the location of PYTHON_HOME using which python, now add the PYTHON_HOME/Scripts to the PATH variable using:

PATH=$PATH:<PYTHON_HOME>\Scripts
export PATH

回答 17

我认为从Python 2.7.9及更高版本开始,预安装了pip,它将位于您的scripts文件夹中。因此,您必须将“ scripts”文件夹添加到路径。我的被​​安装在C:\ Python27 \ Scripts中。检查您的路径,以便您可以相应地更改以下内容,然后转到powershell,将以下代码粘贴到powershell中,然后按Enter键。之后,重新启动,您的问题将得到解决。

[Environment]::SetEnvironmentVariable("Path", "$env:Path;C:\Python27\Scripts", "User")

I think from Python 2.7.9 and higher pip comes pre installed and it will be in your scripts folder. So you have to add the “scripts” folder to the path. Mine is installed in C:\Python27\Scripts. Check yours to see what your path is so that you can alter the below accordingly, then Go to powershell, paste the below code in powershell and hit Enter key. After that, reboot and your issue will be resolved.

[Environment]::SetEnvironmentVariable("Path", "$env:Path;C:\Python27\Scripts", "User")

回答 18

或者,如果您像我一样使用PyCharm(2017.3.3),只需在终端中更改目录并安装:

cd C:\Users\{user}\PycharmProjects\test\venv\Scripts
pip install ..

Or If you are using PyCharm (2017.3.3) like me, just change directory in terminal and install:

cd C:\Users\{user}\PycharmProjects\test\venv\Scripts
pip install ..

回答 19

在Windows环境中,只需在dos shell中执行以下命令即可。

path =%path%; D:\ Program Files \ python3.6.4 \ Scripts; (新路径=当前路径; python脚本文件夹的路径)

In windows environment, just execute below commands in dos shell.

path=%path%;D:\Program Files\python3.6.4\Scripts; (new path=current path;path of the python script folder)


回答 20

我遇到了同样的问题以管理员身份运行Windows PowerShell 可以解决我的问题。

I was facing same issue Run Windows PowerShell as Administrator it resolved my issue.


回答 21

最常见的是:

cmd.exe

python -m pip install --user [name of your module here without brackets]

Most frequently it is:

in cmd.exe write

python -m pip install --user [name of your module here without brackets]

回答 22

更正PATH之后,我仍然收到此错误。

如果您的代码库要求您具有Python的早期版本(在我的情况下为2.7),则它可能是存在pip之前的版本。

这不是很规范,但是安装一个更新的版本对我有用。(我用的是2.7.13)

I continued to recieve this error after correcting my PATH.

If your codebase requires that you have an earlier version of Python (2.7 in my case), it may have been a version prior to the existence of pip.

It’s not very canonical but installing a more recent version worked for me. (I used 2.7.13)


回答 23

我有同样的问题。你只需要去你的

C:\ Python27 \脚本

并将其添加到环境变量中。设置路径后,只需在C:\ Python27 \ Scripts上运行pip.exe文件,然后在cmd中尝试pip。但是,如果没有任何反应,请尝试运行所有pip应用程序,例如pip2.7和pip2.exe。点子将像魅力一样工作。

I had this same issue. You just need to go to your

C:\Python27\Scripts

and add it to environment variables. After path setting just run pip.exe file on C:\Python27\Scripts and then try pip in cmd. But if nothing happens try running all pip applications like pip2.7 and pip2.exe. And pip will work like a charm.


回答 24

解决此问题的一种非常简单的方法是在文件资源管理器中打开安装pip的路径,然后单击该路径,然后键入cmd,这将设置路径,使您的安装方式更容易。

迟到了4年,但几天前我遇到了同样的问题,其他所有方法对我都不起作用。

A very simple way to get around this is to open the path where pip is installed in file explorer, and click on the path, then type cmd, this sets the path, allowing you to install way easier.

4 years late, but I ran into the same issue a couple days ago and all the other methods didn’t work for me.


回答 25

尝试卸载Python,删除其余程序文件,然后重新全新安装。它为我工作。当我迁移到新笔记本电脑并使用迁移软件将软件从旧笔记本电脑迁移到新笔记本电脑时,发生了此错误。是的,效果不是很好。

Try uninstall Python, delete the remaining program files, then install it again fresh. It worked for me. This error happened to me when I migrate to a new laptop and used a migration software to move my software from the old laptop to the new one. And yeah, didn’t work quite well.


回答 26

小小的澄清:在“ Windows 7 64位PC”中,添加...Python34\Scripts到path变量后,pip install pygame对我不起作用。

所以我检查了“ … Python34 \ Scripts”文件夹,它没有pip,但有pip3pip3.4。所以我跑了pip3.4 install pygame .... .whl。有效。

(进一步在已下载pygame...whl文件所在的文件夹中打开一个命令窗口。)

Small clarification: in “Windows 7 64 bit PC”, after adding ...Python34\Scripts to the path variable, pip install pygame didn’t work for me.

So I checked the “…Python34\Scripts” folder, it didn’t have pip, but it had pip3 and pip3.4. So I ran pip3.4 install pygame .... .whl. It worked.

(Further open a command window in the same folder where you have the downloaded pygame...whl file.)


回答 27

对我来说,问题是,在PATH中添加以下内容后,系统未重新启动。

C:\Users\admin\AppData\Local\Programs\Python\Python37\Scripts

For me the issue was, system was not RESTARTED after adding below in PATH.

C:\Users\admin\AppData\Local\Programs\Python\Python37\Scripts


回答 28

安装SQL 2019 Python时,PIP存在一些已知问题,需要修复(步骤7) https://docs.microsoft.com/zh-cn/sql/advanced-analytics/known-issues-for-sql-server-机器学习服务?view = sql-server-ver15

pip配置了需要TLS / SSL的位置,但是Python中的ssl模块不可用。

Workaround
Copy the following files:

libssl-1_1-x64.dll
libcrypto-1_1-x64.dll

from the folder 
C:\Program Files\Microsoft SQL Server\MSSSQL15.MSSQLSERVER\PYTHON_SERVICES\Library\bin
to the folder 
C:\Program Files\Microsoft SQL Server\MSSSQL15.MSSQLSERVER\PYTHON_SERVICES\DLLs

Then open a new DOS command shell prompt.

When installing SQL 2019 Python, there are known issues for PIP which require a fix (step 7) https://docs.microsoft.com/en-us/sql/advanced-analytics/known-issues-for-sql-server-machine-learning-services?view=sql-server-ver15

pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.

Workaround
Copy the following files:

libssl-1_1-x64.dll
libcrypto-1_1-x64.dll

from the folder 
C:\Program Files\Microsoft SQL Server\MSSSQL15.MSSQLSERVER\PYTHON_SERVICES\Library\bin
to the folder 
C:\Program Files\Microsoft SQL Server\MSSSQL15.MSSQLSERVER\PYTHON_SERVICES\DLLs

Then open a new DOS command shell prompt.

回答 29

对于Mac,在终端中运行以下命令

echo  export "PATH=$HOME/Library/Python/2.7/bin:$PATH"

For mac run below command in terminal

echo  export "PATH=$HOME/Library/Python/2.7/bin:$PATH"

如何在Django中以GROUP BY查询?

问题:如何在Django中以GROUP BY查询?

我查询一个模型:

Members.objects.all()

它返回:

Eric, Salesman, X-Shop
Freddie, Manager, X2-Shop
Teddy, Salesman, X2-Shop
Sean, Manager, X2-Shop

我想要的是知道group_by向我的数据库发送查询的最佳Django方法,例如:

Members.objects.all().group_by('designation')

当然,这不起作用。我知道我们可以在上做一些技巧django/db/models/query.py,但我只是很好奇知道如何在不打补丁的情况下进行操作。

I query a model:

Members.objects.all()

And it returns:

Eric, Salesman, X-Shop
Freddie, Manager, X2-Shop
Teddy, Salesman, X2-Shop
Sean, Manager, X2-Shop

What I want is to know the best Django way to fire a group_by query to my database, like:

Members.objects.all().group_by('designation')

Which doesn’t work, of course. I know we can do some tricks on django/db/models/query.py, but I am just curious to know how to do it without patching.


回答 0

如果您打算进行聚合,则可以使用ORM聚合功能

from django.db.models import Count
Members.objects.values('designation').annotate(dcount=Count('designation'))

这导致查询类似于

SELECT designation, COUNT(designation) AS dcount
FROM members GROUP BY designation

并且输出将为以下形式

[{'designation': 'Salesman', 'dcount': 2}, 
 {'designation': 'Manager', 'dcount': 2}]

If you mean to do aggregation you can use the aggregation features of the ORM:

from django.db.models import Count
Members.objects.values('designation').annotate(dcount=Count('designation'))

This results in a query similar to

SELECT designation, COUNT(designation) AS dcount
FROM members GROUP BY designation

and the output would be of the form

[{'designation': 'Salesman', 'dcount': 2}, 
 {'designation': 'Manager', 'dcount': 2}]

回答 1

一个简单的解决方案,但不是正确的方法是使用原始SQL

results = Members.objects.raw('SELECT * FROM myapp_members GROUP BY designation')

另一种解决方案是使用该group_by属性:

query = Members.objects.all().query
query.group_by = ['designation']
results = QuerySet(query=query, model=Members)

现在,您可以遍历结果变量以检索结果。请注意,该group_by文档未记录,在以后的Django版本中可能会更改。

还有…为什么要使用group_by?如果不使用聚合,则可以使用order_by来获得相似的结果。

An easy solution, but not the proper way is to use raw SQL:

results = Members.objects.raw('SELECT * FROM myapp_members GROUP BY designation')

Another solution is to use the group_by property:

query = Members.objects.all().query
query.group_by = ['designation']
results = QuerySet(query=query, model=Members)

You can now iterate over the results variable to retrieve your results. Note that group_by is not documented and may be changed in future version of Django.

And… why do you want to use group_by? If you don’t use aggregation, you can use order_by to achieve an alike result.


回答 2

您也可以使用regroup模板标记按属性分组。从文档:

cities = [
    {'name': 'Mumbai', 'population': '19,000,000', 'country': 'India'},
    {'name': 'Calcutta', 'population': '15,000,000', 'country': 'India'},
    {'name': 'New York', 'population': '20,000,000', 'country': 'USA'},
    {'name': 'Chicago', 'population': '7,000,000', 'country': 'USA'},
    {'name': 'Tokyo', 'population': '33,000,000', 'country': 'Japan'},
]

...

{% regroup cities by country as country_list %}

<ul>
    {% for country in country_list %}
        <li>{{ country.grouper }}
            <ul>
            {% for city in country.list %}
                <li>{{ city.name }}: {{ city.population }}</li>
            {% endfor %}
            </ul>
        </li>
    {% endfor %}
</ul>

看起来像这样:

  • 印度
    • 孟买:19,000,000
    • 加尔各答:15,000,000
  • 美国
    • 纽约:20,000,000
    • 芝加哥:7,000,000
  • 日本
    • 东京:33,000,000

QuerySet我相信它也可以使用。

来源:https : //docs.djangoproject.com/en/2.1/ref/templates/builtins/#regroup

编辑:请注意,如果词典列表未按键排序,则该regroup标签将无法正常运行。它迭代地工作。因此,在将列表(或查询集)传递给regroup标签之前,请先按石斑鱼的键对列表进行排序。

You can also use the regroup template tag to group by attributes. From the docs:

cities = [
    {'name': 'Mumbai', 'population': '19,000,000', 'country': 'India'},
    {'name': 'Calcutta', 'population': '15,000,000', 'country': 'India'},
    {'name': 'New York', 'population': '20,000,000', 'country': 'USA'},
    {'name': 'Chicago', 'population': '7,000,000', 'country': 'USA'},
    {'name': 'Tokyo', 'population': '33,000,000', 'country': 'Japan'},
]

...

{% regroup cities by country as country_list %}

<ul>
    {% for country in country_list %}
        <li>{{ country.grouper }}
            <ul>
            {% for city in country.list %}
                <li>{{ city.name }}: {{ city.population }}</li>
            {% endfor %}
            </ul>
        </li>
    {% endfor %}
</ul>

Looks like this:

  • India
    • Mumbai: 19,000,000
    • Calcutta: 15,000,000
  • USA
    • New York: 20,000,000
    • Chicago: 7,000,000
  • Japan
    • Tokyo: 33,000,000

It also works on QuerySets I believe.

source: https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#regroup

edit: note the regroup tag does not work as you would expect it to if your list of dictionaries is not key-sorted. It works iteratively. So sort your list (or query set) by the key of the grouper before passing it to the regroup tag.


回答 3

您需要按照以下代码片段中的示例进行自定义SQL:

通过子查询自定义SQL

或在在线Django文档中显示的自定义管理器中:

添加额外的Manager方法

You need to do custom SQL as exemplified in this snippet:

Custom SQL via subquery

Or in a custom manager as shown in the online Django docs:

Adding extra Manager methods


回答 4

Django不支持免费的按组分组查询。我以非常糟糕的方式学到了它。如果不使用自定义SQL,则ORM并非旨在支持您想做的事情。您仅限于:

  • 原始sql(即MyModel.objects.raw())
  • cr.execute 句子(以及结果的手工解析)。
  • .annotate() (按句段在.annotate()的子模型中执行句子分组,例如聚合lines_count = Count(’lines’)之类的示例))。

qs您可以调用整个qs.query.group_by = ['field1', 'field2', ...]查询集,但是如果您不知道要编辑的查询,并且不能保证该查询将起作用并且不会破坏QuerySet对象的内部,则可能会有风险。此外,它是一个内部(未记录)的API,您不应直接访问它,而不必担心代码不再与将来的Django版本兼容。

Django does not support free group by queries. I learned it in the very bad way. ORM is not designed to support stuff like what you want to do, without using custom SQL. You are limited to:

  • RAW sql (i.e. MyModel.objects.raw())
  • cr.execute sentences (and a hand-made parsing of the result).
  • .annotate() (the group by sentences are performed in the child model for .annotate(), in examples like aggregating lines_count=Count(‘lines’))).

Over a queryset qs you can call qs.query.group_by = ['field1', 'field2', ...] but it is risky if you don’t know what query are you editing and have no guarantee that it will work and not break internals of the QuerySet object. Besides, it is an internal (undocumented) API you should not access directly without risking the code not being anymore compatible with future Django versions.


回答 5

有一个模块可以让您对Django模型进行分组,并仍然在结果中使用QuerySet:https : //github.com/kako-nawao/django-group-by

例如:

from django_group_by import GroupByMixin

class BookQuerySet(QuerySet, GroupByMixin):
    pass

class Book(Model):
    title = TextField(...)
    author = ForeignKey(User, ...)
    shop = ForeignKey(Shop, ...)
    price = DecimalField(...)

class GroupedBookListView(PaginationMixin, ListView):
    template_name = 'book/books.html'
    model = Book
    paginate_by = 100

    def get_queryset(self):
        return Book.objects.group_by('title', 'author').annotate(
            shop_count=Count('shop'), price_avg=Avg('price')).order_by(
            'name', 'author').distinct()

    def get_context_data(self, **kwargs):
        return super().get_context_data(total_count=self.get_queryset().count(), **kwargs)

‘book / books.html’

<ul>
{% for book in object_list %}
    <li>
        <h2>{{ book.title }}</td>
        <p>{{ book.author.last_name }}, {{ book.author.first_name }}</p>
        <p>{{ book.shop_count }}</p>
        <p>{{ book.price_avg }}</p>
    </li>
{% endfor %}
</ul>

annotate/ aggregate基本Django查询的区别在于使用了相关字段的属性,例如book.author.last_name

如果需要已分组在一起的实例的PK,请添加以下注释:

.annotate(pks=ArrayAgg('id'))

注意:ArrayAgg是Postgres特定的功能,可从Django 1.9开始使用:https : //docs.djangoproject.com/en/1.10/ref/contrib/postgres/aggregates/#arrayagg

There is module that allows you to group Django models and still work with a QuerySet in the result: https://github.com/kako-nawao/django-group-by

For example:

from django_group_by import GroupByMixin

class BookQuerySet(QuerySet, GroupByMixin):
    pass

class Book(Model):
    title = TextField(...)
    author = ForeignKey(User, ...)
    shop = ForeignKey(Shop, ...)
    price = DecimalField(...)

class GroupedBookListView(PaginationMixin, ListView):
    template_name = 'book/books.html'
    model = Book
    paginate_by = 100

    def get_queryset(self):
        return Book.objects.group_by('title', 'author').annotate(
            shop_count=Count('shop'), price_avg=Avg('price')).order_by(
            'name', 'author').distinct()

    def get_context_data(self, **kwargs):
        return super().get_context_data(total_count=self.get_queryset().count(), **kwargs)

‘book/books.html’

<ul>
{% for book in object_list %}
    <li>
        <h2>{{ book.title }}</td>
        <p>{{ book.author.last_name }}, {{ book.author.first_name }}</p>
        <p>{{ book.shop_count }}</p>
        <p>{{ book.price_avg }}</p>
    </li>
{% endfor %}
</ul>

The difference to the annotate/aggregate basic Django queries is the use of the attributes of a related field, e.g. book.author.last_name.

If you need the PKs of the instances that have been grouped together, add the following annotation:

.annotate(pks=ArrayAgg('id'))

NOTE: ArrayAgg is a Postgres specific function, available from Django 1.9 onwards: https://docs.djangoproject.com/en/1.10/ref/contrib/postgres/aggregates/#arrayagg


回答 6

文档说您可以使用值对queryset进行分组。

class Travel(models.Model):
    interest = models.ForeignKey(Interest)
    user = models.ForeignKey(User)
    time = models.DateTimeField(auto_now_add=True)

# Find the travel and group by the interest:

>>> Travel.objects.values('interest').annotate(Count('user'))
<QuerySet [{'interest': 5, 'user__count': 2}, {'interest': 6, 'user__count': 1}]>
# the interest(id=5) had been visited for 2 times, 
# and the interest(id=6) had only been visited for 1 time.

>>> Travel.objects.values('interest').annotate(Count('user', distinct=True)) 
<QuerySet [{'interest': 5, 'user__count': 1}, {'interest': 6, 'user__count': 1}]>
# the interest(id=5) had been visited by only one person (but this person had 
#  visited the interest for 2 times

您可以找到所有书籍,并使用以下代码按名称分组:

Book.objects.values('name').annotate(Count('id')).order_by() # ensure you add the order_by()

你可以在这里看一些指南。

The document says that you can use values to group the queryset .

class Travel(models.Model):
    interest = models.ForeignKey(Interest)
    user = models.ForeignKey(User)
    time = models.DateTimeField(auto_now_add=True)

# Find the travel and group by the interest:

>>> Travel.objects.values('interest').annotate(Count('user'))
<QuerySet [{'interest': 5, 'user__count': 2}, {'interest': 6, 'user__count': 1}]>
# the interest(id=5) had been visited for 2 times, 
# and the interest(id=6) had only been visited for 1 time.

>>> Travel.objects.values('interest').annotate(Count('user', distinct=True)) 
<QuerySet [{'interest': 5, 'user__count': 1}, {'interest': 6, 'user__count': 1}]>
# the interest(id=5) had been visited by only one person (but this person had 
#  visited the interest for 2 times

You can find all the books and group them by name using this code:

Book.objects.values('name').annotate(Count('id')).order_by() # ensure you add the order_by()

You can watch some cheet sheet here.


回答 7

如果我没有记错的话,可以使用what -query-set .group_by = [‘ field ‘]

If I’m not mistaking you can use, whatever-query-set.group_by=[‘field‘]


回答 8

from django.db.models import Sum
Members.objects.annotate(total=Sum(designation))

首先,您需要导入Sum,然后..

from django.db.models import Sum
Members.objects.annotate(total=Sum(designation))

first you need to import Sum then ..


pip在哪里安装其软件包?

问题:pip在哪里安装其软件包?

我激活了已安装pip的virtualenv。我做了

pip3 install Django==1.8

和Django成功下载。现在,我想打开Django文件夹。文件夹在哪里?通常它会在“下载”中,但是我不确定如果在virtualenv中使用pip安装它会在哪里。

I activated a virtualenv which has pip installed. I did

pip3 install Django==1.8

and Django successfully downloaded. Now, I want to open up the Django folder. Where is the folder located? Normally it would be in “downloads” but I’m not sure where it would be if I installed it using pip in a virtualenv.


回答 0

virtualenv一起使用时,pip通常会在路径中安装软件包<virtualenv_name>/lib/<python_ver>/site-packages

例如,我使用Python 2.7 创建了一个名为venv_test的测试virtualenv ,该文件夹位于中。djangovenv_test/lib/python2.7/site-packages/django

pip when used with virtualenv will generally install packages in the path <virtualenv_name>/lib/<python_ver>/site-packages.

For example, I created a test virtualenv named venv_test with Python 2.7, and the django folder is in venv_test/lib/python2.7/site-packages/django.


回答 1

根据大众需求,通过发布的答案提供了一个选项:

pip show <package name>将提供Windows和macOS的位置,我猜是任何系统。:)

例如:

> pip show cvxopt
Name: cvxopt
Version: 1.2.0
...
Location: /usr/local/lib/python2.7/site-packages

By popular demand, an option provided via posted answer:

pip show <package name> will provide the location for Windows and macOS, and I’m guessing any system. :)

For example:

> pip show cvxopt
Name: cvxopt
Version: 1.2.0
...
Location: /usr/local/lib/python2.7/site-packages

回答 2

pip list -v可用于列出软件包的安装位置,该位置在https://pip.pypa.io/zh/stable/news/#b1-2018-03-31中引入

当列表命令与“ -v”选项一起运行时,显示安装位置。(#979)

>pip list -v
Package                  Version   Location                                                             Installer
------------------------ --------- -------------------------------------------------------------------- ---------
alabaster                0.7.12    c:\users\me\appdata\local\programs\python\python38\lib\site-packages pip
apipkg                   1.5       c:\users\me\appdata\local\programs\python\python38\lib\site-packages pip
argcomplete              1.10.3    c:\users\me\appdata\local\programs\python\python38\lib\site-packages pip
astroid                  2.3.3     c:\users\me\appdata\local\programs\python\python38\lib\site-packages pip
...

更新pip10.0.0b1中引入了此功能。在Ubuntu 18.04上,pippip3安装有sudo apt install python-pip或是sudo apt install python3-pip9.0.1的版本,但没有此功能。检查https://github.com/pypa/pip/issues/5599,了解升级pip或升级的合适方法pip3

pip list -v can be used to list packages’ install locations, introduced in https://pip.pypa.io/en/stable/news/#b1-2018-03-31

Show install locations when list command ran with “-v” option. (#979)

>pip list -v
Package                  Version   Location                                                             Installer
------------------------ --------- -------------------------------------------------------------------- ---------
alabaster                0.7.12    c:\users\me\appdata\local\programs\python\python38\lib\site-packages pip
apipkg                   1.5       c:\users\me\appdata\local\programs\python\python38\lib\site-packages pip
argcomplete              1.10.3    c:\users\me\appdata\local\programs\python\python38\lib\site-packages pip
astroid                  2.3.3     c:\users\me\appdata\local\programs\python\python38\lib\site-packages pip
...

Update: This feature is introduced in pip 10.0.0b1. On Ubuntu 18.04, pip or pip3 installed with sudo apt install python-pip or sudo apt install python3-pip is 9.0.1 which doesn’t have this feature. Check https://github.com/pypa/pip/issues/5599 for suitable ways of upgrading pip or pip3.


回答 3

默认情况下,在Linux上,Pip将软件包安装到/usr/local/lib/python2.7/dist-packages。

在安装过程中使用virtualenv或–user将更改此默认位置。如果使用,请pip show确保使用的用户正确,否则pip可能看不到您所引用的软件包。

By default, on Linux, Pip installs packages to /usr/local/lib/python2.7/dist-packages.

Using virtualenv or –user during install will change this default location. If you use pip show make sure you are using the right user or else pip may not see the packages you are referencing.


回答 4

在Python解释器或脚本中,您可以执行

import site
site.getsitepackages() # list of global package locations

site.getusersitepackages() #string for user-specific package location

位置安装了第三方软件包(不在核心Python发行版中)。

在MacOS上我的Brew安装的Python上,前者输出

['/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages']

pip show如上一个答案所述,它规范化到所输出的相同路径:

$ readlink -f /usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages
/usr/local/lib/python3.7/site-packages

参考:https : //docs.python.org/3/library/site.html#site.getsitepackages

In a Python interpreter or script, you can do

import site
site.getsitepackages() # list of global package locations

and

site.getusersitepackages() #string for user-specific package location

for locations 3rd party packages (those not in the core Python distribution) are installed to.

On my Brew-installed Python on MacOS, the former outputs

['/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages'],

which canonicalizes to the same path output by pip show, as mentioned in a previous answer:

$ readlink -f /usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages
/usr/local/lib/python3.7/site-packages

Reference: https://docs.python.org/3/library/site.html#site.getsitepackages


在Django中,“子弹”是什么?

问题:在Django中,“子弹”是什么?

当我阅读Django代码时,我经常在模型中看到所谓的“子弹”。我不太清楚这是什么,但是我知道它与URL有关。应该如何以及何时使用这种this子?

(我已经在本词汇表中阅读了其定义。)

When I read Django code I often see in models what is called a “slug”. I am not quite sure what this is, but I do know it has something to do with URLs. How and when is this slug-thing supposed to be used?

(I have read its definition in this glossary.)


回答 0

“子弹”是一种通常使用已获得的数据生成有效URL的方法。例如,a使用文章标题来生成URL。我建议通过给定标题(或另一段数据)的函数来生成段,而不要手动设置它。

一个例子:

<title> The 46 Year Old Virgin </title>
<content> A silly comedy movie </content>
<slug> the-46-year-old-virgin </slug>

现在,我们假设我们有一个Django模型,例如:

class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField(max_length=1000)
    slug = models.SlugField(max_length=40)

您将如何使用URL和有意义的名称引用该对象?例如,您可以使用Article.id,因此URL如下所示:

www.example.com/article/23

或者,您可能希望像这样引用标题:

www.example.com/article/The 46 Year Old Virgin

由于网址中的空格无效,因此必须将其替换为%20,这将导致:

www.example.com/article/The%2046%20Year%20Old%20Virgin

两次尝试都不会产生非常有意义且易于阅读的URL。这个更好:

www.example.com/article/the-46-year-old-virgin

在此示例中,the-46-year-old-virgin是一个子弹:它是通过将所有字母缩进小写并用连字符替换空格来从标题创建的-

另请参见此网页的URL。

A “slug” is a way of generating a valid URL, generally using data already obtained. For instance, a slug uses the title of an article to generate a URL. I advise to generate the slug by means of a function, given the title (or another piece of data), rather than setting it manually.

An example:

<title> The 46 Year Old Virgin </title>
<content> A silly comedy movie </content>
<slug> the-46-year-old-virgin </slug>

Now let’s pretend that we have a Django model such as:

class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField(max_length=1000)
    slug = models.SlugField(max_length=40)

How would you reference this object with a URL and with a meaningful name? You could for instance use Article.id so the URL would look like this:

www.example.com/article/23

Or, you might want to reference the title like this:

www.example.com/article/The 46 Year Old Virgin

Since spaces aren’t valid in URLs, they must be replaced by %20, which results in:

www.example.com/article/The%2046%20Year%20Old%20Virgin

Both attempts are not resulting in very meaningful, easy-to-read URL. This is better:

www.example.com/article/the-46-year-old-virgin

In this example, the-46-year-old-virgin is a slug: it is created from the title by down-casing all letters, and replacing spaces by hyphens -.

Also see the URL of this very web page for another example.


回答 1

如果我可以提供一些历史背景:

术语“弹头”与铸造金属铅,在这种情况下,外面的新闻字体被做事情。然后,每张纸的字体工厂都会定期重新熔化,并用新鲜的模具重新铸造,因为经过多次印刷后,它们已经磨损了。像我这样的学徒从那里开始了他们的职业生涯,并一路攀升到了顶峰(不再有)。

排版者必须以倒排的方式撰写文章文字,并以明智的方式堆叠主角。因此,在打印时,字母将直接在纸上。所有的印刷机都能像打印的报纸一样快地阅读报纸。因此,(如蜗牛)和慢故事(最后一个要修复的故事)在板凳上等待着很多,只能通过拳头字母来识别,大部分标题通常更易读。一些“热门”新闻在板凳上等待着,可能在最后组装和确定印刷之前进行最后一分钟的更正(晚上用纸)。

Django来自堪萨斯州《劳伦斯》杂志的办公室。也许还有一些印刷术语仍然存在。django爱好者和来自法国的友好的老-男孩。

If I may provide some historical context :

The term “slug” has to do with casting metal—lead, in this case—out of which the press fonts were made. Every paper then had its fonts factory regularly re-melted and recast in fresh molds, since after many prints they became worn out. Apprentices like me started their career there, and went all the way to the top (not anymore).

Typographs had to compose the text of an article in a backward manner with lead characters stacked in a wise. So at printing time the letters would be straight on the paper. All typographs could read the newspaper mirrored as fast as the printed one. Therefore the slugs, (like snails) also the slow stories (the last to be fixed) were many on the bench waiting, solely identified by their fist letters, mostly the whole title generally more readable. Some “hot” news were waiting there on the bench, for possible last minute correction, (Evening paper) before last assembly and definitive printing.

Django emerged from the offices of the Lawrence journal in Kansas. Where probably some printing jargon still lingers. A-django-enthusiast-&-friendly-old-slug-boy-from-France.


回答 2

“子弹”一词来自报纸生产的世界。

这是制作过程中故事的非正式名称。随着故事的发展,从节拍记者(假设这些故事甚至还存在吗?)一直到编辑器再到“印刷机”,这就是它所引用的名称,例如,“您是否已修复了’凯特和威廉的故事?”。

某些系统(例如Django)使用slug作为URL的一部分来定位故事,例如www.mysite.com/archives/kate-and-william

甚至Stack Overflow本身也可以使用GEB-ish (a)自引用进行此操作/programming/427102/what-is-a-slug-in-django/427201#427201,尽管您可以将其替换为blahblah,但仍然可以。

它可能甚至早于该日期,因为编剧在每个场景的开始处都有“条形线”,这基本上设置了该场景的背景(位置,时间等)。这非常相似,是随后内容的序言或序言。

在Linotype机器上,子弹是由单个字母形式创建的单线金属片。通过为整个行制作一个块,这大大改善了旧的逐字符合成。

尽管以下是纯粹的推测,但“鼻涕虫”的早期含义是使用伪造的硬币(必须以某种方式加以按压)。我可以设想将用法转换为印刷术语(因为必须使用原始字符压制嵌条),然后从“金属片”定义更改为“故事摘要”定义。从那里开始,从正确的打印到在线世界仅一步之遥。


(a)道格拉斯·霍夫施塔特Douglas Hofstadter )的作品《巴赫·戈德尔·埃舍尔》(Godel Escher,Bach),我(至少)认为这是伟大的现代知识分子作品之一。您还应该查看他的其他作品“ Metamagical Themas”。

The term ‘slug’ comes from the world of newspaper production.

It’s an informal name given to a story during the production process. As the story winds its path from the beat reporter (assuming these even exist any more?) through to editor through to the “printing presses”, this is the name it is referenced by, e.g., “Have you fixed those errors in the ‘kate-and-william’ story?”.

Some systems (such as Django) use the slug as part of the URL to locate the story, an example being www.mysite.com/archives/kate-and-william.

Even Stack Overflow itself does this, with the GEB-ish(a) self-referential https://stackoverflow.com/questions/427102/what-is-a-slug-in-django/427201#427201, although you can replace the slug with blahblah and it will still find it okay.

It may even date back earlier than that, since screenplays had “slug lines” at the start of each scene, which basically sets the background for that scene (where, when, and so on). It’s very similar in that it’s a precis or preamble of what follows.

On a Linotype machine, a slug was a single line piece of metal which was created from the individual letter forms. By making a single slug for the whole line, this greatly improved on the old character-by-character compositing.

Although the following is pure conjecture, an early meaning of slug was for a counterfeit coin (which would have to be pressed somehow). I could envisage that usage being transformed to the printing term (since the slug had to be pressed using the original characters) and from there, changing from the ‘piece of metal’ definition to the ‘story summary’ definition. From there, it’s a short step from proper printing to the online world.


(a) “Godel Escher, Bach”, by one Douglas Hofstadter, which I (at least) consider one of the great modern intellectual works. You should also check out his other work, “Metamagical Themas”.


回答 3

Slug是一个报纸术语。子弹是某事物的简短标签,仅包含字母,数字,下划线或连字符。它们通常在URL中使用。(如Django文档)

Django中的Slug字段用于为动态创建的网页存储和生成有效的URL

就像您在Stack Overflow上添加此问题的方式一样,并生成了一个动态页面,当您在地址栏中看到时,您会看到问题标题带有“-”代替空格。这正是田的工作。

您输入的标题是这样的->在Django中,“子弹”是什么?

将其存储到slug字段中后,它变成“ what-is-a-slug-in-django”(请参阅​​此页面的URL)

Slug is a newspaper term. A slug is a short label for something, containing only letters, numbers, underscores or hyphens. They’re generally used in URLs. (as in Django docs)

A slug field in Django is used to store and generate valid URLs for your dynamically created web pages.

Just like the way you added this question on Stack Overflow and a dynamic page was generated and when you see in the address bar you will see your question title with “-” in place of the spaces. That’s exactly the job of a slug field.

The title entered by you was something like this -> What is a “slug” in Django?

On storing it into a slug field it becomes “what-is-a-slug-in-django” (see URL of this page)


回答 4

这里

“ Slug”是报纸上的术语,但此处的含义是URL的最后一部分。例如,标题为“关于Django的一点”的帖子将自动变为“ bit-about-django”(当然,如果您不喜欢自动生成的子弹,则可以轻松地对其进行更改)。

From here.

“Slug” is a newspaper term, but what it means here is the final bit of the URL. For example, a post with the title, “A bit about Django” would become, “bit-about-django” automatically (you can, of course, change it easily if you don’t like the auto-generated slug).


回答 5

它是URL的描述性部分,可以使它更具人工描述性,但不一定是Web服务器所必需的- 在Django中,“子弹”是什么?slug是“ in-django-what-is-a-slug”,但是不使用slug来确定所服务页面(至少在此站点上)

It’s a descriptive part of the URL that is there to make it more human descriptive, but without necessarily being required by the web server – in What is a “slug” in Django? the slug is ‘in-django-what-is-a-slug’, but the slug is not used to determine the page served (on this site at least)


回答 6

Slug是特定内容的URL友好短标签。它仅包含字母,数字,下划线或连字符。子弹通常与各自的内容一起保存,并作为URL字符串传递。

Slug可以使用SlugField创建

例如:

class Article(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(max_length=100)

如果您想使用标题作为标题,django有一个简单的函数称为 slugify

from django.template.defaultfilters import slugify

class Article(models.Model):
    title = models.CharField(max_length=100)

    def slug(self):
        return slugify(self.title)

如果需要唯一性,请添加unique=True子弹字段。

例如,从前面的示例中:

class Article(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(max_length=100, unique=True)

您是否懒于进行处理?不用担心,此插件将为您提供帮助。 django-autoslug

Slug is a URL friendly short label for specific content. It only contain Letters, Numbers, Underscores or Hyphens. Slugs are commonly save with the respective content and it pass as a URL string.

Slug can create using SlugField

Ex:

class Article(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(max_length=100)

If you want to use title as slug, django has a simple function called slugify

from django.template.defaultfilters import slugify

class Article(models.Model):
    title = models.CharField(max_length=100)

    def slug(self):
        return slugify(self.title)

If it needs uniqueness, add unique=True in slug field.

for instance, from the previous example:

class Article(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(max_length=100, unique=True)

Are you lazy to do slug process ? don’t worry, this plugin will help you. django-autoslug


回答 7

也可以在django-admin上自动启动。在ModelAdmin上添加:

prepopulated_fields = {'slug': ('title', )}

如这里:

class ArticleAdmin(admin.ModelAdmin):
    list_display = ('title', 'slug')
    search_fields = ('content', )

    prepopulated_fields = {'slug': ('title', )}

Also auto slug at django-admin. Added at ModelAdmin:

prepopulated_fields = {'slug': ('title', )}

As here:

class ArticleAdmin(admin.ModelAdmin):
    list_display = ('title', 'slug')
    search_fields = ('content', )

    prepopulated_fields = {'slug': ('title', )}

回答 8

ug

某物的简短标签,仅包含字母,数字,下划线或连字符。它们通常在URL中使用。例如,在典型的博客条目URL中:

https://www.djangoproject.com/weblog/2008/apr/12/spring/ 最后一点(弹簧)是弹头。

slug

A short label for something, containing only letters, numbers, underscores or hyphens. They’re generally used in URLs. For example, in a typical blog entry URL:

https://www.djangoproject.com/weblog/2008/apr/12/spring/ the last bit (spring) is the slug.


如何在Django中进行调试,好方法?[关闭]

问题:如何在Django中进行调试,好方法?[关闭]

因此,我开始学习使用Python和更高版本的Django进行编码。第一次很难查看回溯,实际上要弄清楚我做错了什么以及语法错误在哪里。现在已经过去了一段时间,而且我想我已经有了调试Django代码的例程。由于这是我编码经验的早期,所以我坐下来,想知道自己的做法是否无效,并且可以更快地完成。我通常设法找到并纠正代码中的错误,但是我想知道是否应该更快地执行该操作?

我通常只使用Django启用时提供的调试信息。当事情按我预期的那样结束时,我因语法错误而使代码流中断很多,然后查看流中该点的变量以找出其中的代码在做什么,而不是我想要的。

但这可以改善吗?是否有一些好的工具或更好的方法来调试Django代码?

So, I started learning to code in Python and later Django. The first times it was hard looking at tracebacks and actually figure out what I did wrong and where the syntax error was. Some time has passed now and some way along the way, I guess I got a routine in debugging my Django code. As this was done early in my coding experience, I sat down and wondered if how I was doing this was ineffective and could be done faster. I usually manage to find and correct the bugs in my code, but I wonder if I should be doing it faster?

I usually just use the debug info Django gives when enabled. When things do end up as I thought it would, I break the code flow a lot with a syntax error, and look at the variables at that point in the flow to figure out, where the code does something other than what I wanted.

But can this be improved? Are there some good tools or better ways to debug your Django code?


回答 0

有很多方法可以做到,但是最直接的方法就是简单地使用Python调试器。只需将以下行添加到Django视图函数中:

import pdb; pdb.set_trace()

要么

breakpoint()  #from Python3.7

如果尝试在浏览器中加载该页面,浏览器将挂起,并且提示您对实际执行的代码进行调试。

但是,还有其他选择(我不推荐使用):

* return HttpResponse({variable to inspect})

* print {variable to inspect}

* raise Exception({variable to inspect})

但是强烈建议所有类型的Python代码都使用Python调试器(pdb)。如果你已经到PDB,你想也想看看IPDB使用IPython中进行调试。

对pdb的一些更有用的扩展是

pdb ++,由 Antash建议。

pudb,由 PatDuJour建议。

Seafangs建议在Django中使用Python调试器

There are a bunch of ways to do it, but the most straightforward is to simply use the Python debugger. Just add following line in to a Django view function:

import pdb; pdb.set_trace()

or

breakpoint()  #from Python3.7

If you try to load that page in your browser, the browser will hang and you get a prompt to carry on debugging on actual executing code.

However there are other options (I am not recommending them):

* return HttpResponse({variable to inspect})

* print {variable to inspect}

* raise Exception({variable to inspect})

But the Python Debugger (pdb) is highly recommended for all types of Python code. If you are already into pdb, you’d also want to have a look at IPDB that uses ipython for debugging.

Some more useful extension to pdb are

pdb++, suggested by Antash.

pudb, suggested by PatDuJour.

Using the Python debugger in Django, suggested by Seafangs.


回答 1

我真的很喜欢Werkzeug的交互式调试器。它与Django的调试页面相似,不同之处在于您在回溯的每个级别上都获得了一个交互式shell。如果使用django-extensions,则会得到一个runserver_plus管理命令,该命令启动开发服务器,并为您提供Werkzeug的异常调试器。

当然,您只应在本地运行此命令,因为它使拥有浏览器的任何人都有权在服务器的上下文中执行任意python代码。

I really like Werkzeug‘s interactive debugger. It’s similar to Django’s debug page, except that you get an interactive shell on every level of the traceback. If you use the django-extensions, you get a runserver_plus managment command which starts the development server and gives you Werkzeug’s debugger on exceptions.

Of course, you should only run this locally, as it gives anyone with a browser the rights to execute arbitrary python code in the context of the server.


回答 2

模板标记的小工具:

@register.filter 
def pdb(element):
    import pdb; pdb.set_trace()
    return element

现在,您可以在模板内执行{{ template_var|pdb }}并输入一个pdb会话(假设您正在运行本地devel服务器),您可以在其中检查element您的心脏内容。

这是查看对象到达模板时发生了什么情况的一种很好的方法。

A little quickie for template tags:

@register.filter 
def pdb(element):
    import pdb; pdb.set_trace()
    return element

Now, inside a template you can do {{ template_var|pdb }} and enter a pdb session (given you’re running the local devel server) where you can inspect element to your heart’s content.

It’s a very nice way to see what’s happened to your object when it arrives at the template.


回答 3

有一些工具可以很好地协作,并且可以使您的调试任务更轻松。

最重要的是Django调试工具栏

然后,您需要使用Python 日志记录工具进行良好的日志记录。您可以将日志输出发送到日志文件,但是更简单的选择是将日志输出发送到firepython。要使用此功能,您需要使用带有firebug扩展名的Firefox浏览器。Firepython包含一个firebug插件,该插件将在Firebug标签中显示所有服务器端日志。

Firebug本身对于调试您开发的任何应用程序的Javascript方面也至关重要。(假设您当然有一些JS代码)。

我还喜欢使用django-viewtools通过pdb交互式地调试视图,但是我并没有那么多地使用它。

还有诸如推土机之类的更有用的工具来跟踪内存泄漏(SO的答案中也提供了其他一些很好的建议来进行内存跟踪)。

There are a few tools that cooperate well and can make your debugging task easier.

Most important is the Django debug toolbar.

Then you need good logging using the Python logging facility. You can send logging output to a log file, but an easier option is sending log output to firepython. To use this you need to use the Firefox browser with the firebug extension. Firepython includes a firebug plugin that will display any server-side logging in a Firebug tab.

Firebug itself is also critical for debugging the Javascript side of any app you develop. (Assuming you have some JS code of course).

I also liked django-viewtools for debugging views interactively using pdb, but I don’t use it that much.

There are more useful tools like dozer for tracking down memory leaks (there are also other good suggestions given in answers here on SO for memory tracking).


回答 4

我使用PyCharm(与Eclipse相同的pydev引擎)。确实可以帮助我直观地逐步查看我的代码并查看正在发生的事情。

I use PyCharm (same pydev engine as eclipse). Really helps me to visually be able to step through my code and see what is happening.


回答 5

到目前为止,几乎所有内容都已提及,因此,我仅补充一点,而不是pdb.set_trace()可以使用ipdb.set_trace()(它使用iPython),因此功能更强大(自动完成功能和其他功能)。这需要ipdb包,因此您只需要pip install ipdb

Almost everything has been mentioned so far, so I’ll only add that instead of pdb.set_trace() one can use ipdb.set_trace() which uses iPython and therefore is more powerful (autocomplete and other goodies). This requires ipdb package, so you only need to pip install ipdb


回答 6

我推django-pdbPyPI中。这是一个简单的应用程序,这意味着您不必每次想进入pdb都需要编辑源代码。

安装只是…

  1. pip install django-pdb
  2. 添加'django_pdb'到您的INSTALLED_APPS

您现在可以运行:manage.py runserver --pdb在每个视图的开始处进入pdb …

bash: manage.py runserver --pdb
Validating models...

0 errors found
Django version 1.3, using settings 'testproject.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

GET /
function "myview" in testapp/views.py:6
args: ()
kwargs: {}

> /Users/tom/github/django-pdb/testproject/testapp/views.py(7)myview()
-> a = 1
(Pdb)

并运行:manage.py test --pdb在测试失败/错误时进入pdb …

bash: manage.py test testapp --pdb
Creating test database for alias 'default'...
E
======================================================================
>>> test_error (testapp.tests.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File ".../django-pdb/testproject/testapp/tests.py", line 16, in test_error
    one_plus_one = four
NameError: global name 'four' is not defined
======================================================================

> /Users/tom/github/django-pdb/testproject/testapp/tests.py(16)test_error()
-> one_plus_one = four
(Pdb)

该项目托管在GitHub上,当然欢迎您贡献。

I’ve pushed django-pdb to PyPI. It’s a simple app that means you don’t need to edit your source code every time you want to break into pdb.

Installation is just…

  1. pip install django-pdb
  2. Add 'django_pdb' to your INSTALLED_APPS

You can now run: manage.py runserver --pdb to break into pdb at the start of every view…

bash: manage.py runserver --pdb
Validating models...

0 errors found
Django version 1.3, using settings 'testproject.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

GET /
function "myview" in testapp/views.py:6
args: ()
kwargs: {}

> /Users/tom/github/django-pdb/testproject/testapp/views.py(7)myview()
-> a = 1
(Pdb)

And run: manage.py test --pdb to break into pdb on test failures/errors…

bash: manage.py test testapp --pdb
Creating test database for alias 'default'...
E
======================================================================
>>> test_error (testapp.tests.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File ".../django-pdb/testproject/testapp/tests.py", line 16, in test_error
    one_plus_one = four
NameError: global name 'four' is not defined
======================================================================

> /Users/tom/github/django-pdb/testproject/testapp/tests.py(16)test_error()
-> one_plus_one = four
(Pdb)

The project’s hosted on GitHub, contributions are welcome of course.


回答 7

调试python的最简单方法是使用PTVS(适用于Visual Studio的Python工具),尤其是对于使用Visual Studio的程序员而言。步骤很简单:

  1. http://pytools.codeplex.com/下载并安装
  2. 设置断点并按F5。
  3. 您的断点被击中,您可以像调试C#/ C ++程序一样轻松地查看/更改变量。
  4. 就这样 :)

如果要使用PTVS调试Django,则需要执行以下操作:

  1. 在“项目设置”的“常规”选项卡中,将“启动文件”设置为“ manage.py”,这是Django程序的入口点。
  2. 在项目设置-调试选项卡中,将“脚本参数”设置为“ runserver –noreload”。关键是这里的“ –noreload”。如果您不设置它,您的断点将不会被击中。
  3. 好好享受。

The easiest way to debug python – especially for programmers that are used to Visual Studio – is using PTVS (Python Tools for Visual Studio). The steps are simple:

  1. Download and install it from http://pytools.codeplex.com/
  2. Set breakpoints and press F5.
  3. Your breakpoint is hit, you can view/change the variables as easy as debugging C#/C++ programs.
  4. That’s all :)

If you want to debug Django using PTVS, you need to do the following:

  1. In Project settings – General tab, set “Startup File” to “manage.py”, the entry point of the Django program.
  2. In Project settings – Debug tab, set “Script Arguments” to “runserver –noreload”. The key point is the “–noreload” here. If you don’t set it, your breakpoints won’t be hit.
  3. Enjoy it.

回答 8

我将pyDev与Eclipse 搭配使用非常好,设置断点,进入代码,查看任何对象和变量的值,然后尝试。

I use pyDev with Eclipse really good, set break points, step into code, view values on any objects and variables, try it.


回答 9

我使用PyCharm并一直坚持下去。它花了我一点钱,但我不得不说,我摆脱它的好处是无价的。我尝试从控制台进行调试,但我确实给予了很多荣誉,他们可以做到这一点,但是对我而言,能够直观地调试我的应用程序真是太好了。

我不得不说,PyCharm确实占用了大量内存。但是话又说回来,生活中没有什么是免费的。他们只是带有最新版本3。它在Django,Flask和Google AppEngine中也能很好地发挥作用。因此,总而言之,对于任何开发人员来说,这都是一个非常方便的工具。

如果您尚未使用它,建议您试用30天,以了解PyCharm的功能。我确定还有其他工具,例如Aptana。但是我想我也喜欢PyCharm的外观。我在那里调试我的应用程序感到非常自在。

I use PyCharm and stand by it all the way. It cost me a little but I have to say the advantage that I get out of it is priceless. I tried debugging from console and I do give people a lot of credit who can do that, but for me being able to visually debug my application(s) is great.

I have to say though, PyCharm does take a lot of memory. But then again, nothing good is free in life. They just came with their latest version 3. It also plays very well with Django, Flask and Google AppEngine. So, all in all, I’d say it’s a great handy tool to have for any developer.

If you are not using it yet, I’d recommend to get the trial version for 30 days to take a look at the power of PyCharm. I’m sure there are other tools also available, such as Aptana. But I guess I just also like the way PyCharm looks. I feel very comfortable debugging my apps there.


回答 10

有时候,当我想探索一种特定的方法并且召唤pdb太麻烦时,我会添加:

import IPython; IPython.embed()

IPython.embed() 启动一个IPython shell,该shell可以从调用它的地方访问局部变量。

Sometimes when I wan to explore around in a particular method and summoning pdb is just too cumbersome, I would add:

import IPython; IPython.embed()

IPython.embed() starts an IPython shell which have access to the local variables from the point where you call it.


回答 11

从我的角度来看,我们可以将常见的代码调试任务分解为三种不同的使用模式:

  1. 出现了一个异常runserver_plus’Werkzeug调试器进行了救援。在所有跟踪级别上运行自定义代码的能力是一个杀手er。而且,如果您完全陷入困境,则可以创建一个Gist,只需单击即可共享。
  2. 页面被渲染,但是结果是错误的:再次,Werkzeug摇摆不定。要在代码中创建断点,只需键入assert False要停止的位置。
  3. 代码工作不正确,但快速浏览无济于事。最有可能是算法问题。叹。然后,我通常火了调试器控制台PuDBimport pudb; pudb.set_trace()。与[i] pdb相比,主要优点是PuDB(看起来像80年代)使设置自定义监视表达式变得轻而易举。使用GUI调试一堆嵌套循环要简单得多。

啊,是的,模板的问题。最常见的问题(对我和我的同事而言)是错误的上下文:您没有变量,或者您的变量没有某些属性。如果您使用的是调试工具栏,则只需在“模板”部分检查上下文,或者,如果不够用的话,可以在填充完上下文后在视图代码中设置一个中断。

这样吧。

From my perspective, we could break down common code debugging tasks into three distinct usage patterns:

  1. Something has raised an exception: runserver_plus‘ Werkzeug debugger to the rescue. The ability to run custom code at all the trace levels is a killer. And if you’re completely stuck, you can create a Gist to share with just a click.
  2. Page is rendered, but the result is wrong: again, Werkzeug rocks. To make a breakpoint in code, just type assert False in the place you want to stop at.
  3. Code works wrong, but the quick look doesn’t help. Most probably, an algorithmic problem. Sigh. Then I usually fire up a console debugger PuDB: import pudb; pudb.set_trace(). The main advantage over [i]pdb is that PuDB (while looking as you’re in 80’s) makes setting custom watch expressions a breeze. And debugging a bunch of nested loops is much simpler with a GUI.

Ah, yes, the templates’ woes. The most common (to me and my colleagues) problem is a wrong context: either you don’t have a variable, or your variable doesn’t have some attribute. If you’re using debug toolbar, just inspect the context at the “Templates” section, or, if it’s not sufficient, set a break in your views’ code just after your context is filled up.

So it goes.


回答 12

我强烈建议使用epdb(扩展的Python调试器)。

https://bitbucket.org/dugan/epdb

我喜欢epdb用于调试Django或其他Python网络服务器的一件事是epdb.serve()命令。这将设置一个跟踪并将其提供给您可以连接到的本地端口。典型用例:

我认为我要逐步进行。我将在要设置跟踪的位置插入以下内容。

import epdb; epdb.serve()

执行此代码后,我将打开一个Python解释器并连接到服务实例。我可以分析所有值,并使用标准的pdb命令(如n,s等)逐步执行代码。

In [2]: import epdb; epdb.connect()
(Epdb) request
<WSGIRequest
path:/foo,
GET:<QueryDict: {}>, 
POST:<QuestDict: {}>,
...
>
(Epdb) request.session.session_key
'i31kq7lljj3up5v7hbw9cff0rga2vlq5'
(Epdb) list
 85         raise some_error.CustomError()
 86 
 87     # Example login view
 88     def login(request, username, password):
 89         import epdb; epdb.serve()
 90  ->     return my_login_method(username, password)
 91
 92     # Example view to show session key
 93     def get_session_key(request):
 94         return request.session.session_key
 95

您可以随时了解有关键入epdb help的更多信息。

如果要同时服务或连接到多个epdb实例,则可以指定要监听的端口(默认为8080)。即

import epdb; epdb.serve(4242)

>> import epdb; epdb.connect(host='192.168.3.2', port=4242)

如果未指定,则主机默认为“ localhost”。我在这里进行了演示,以演示如何使用它来调试本地实例以外的其他东西,例如本地LAN上的开发服务器。显然,如果执行此操作,请注意设置的跟踪永远不会进入生产服务器!

快速说明一下,您仍然可以使用epdb(import epdb; epdb.set_trace())做与已接受答案相同的操作,但是由于我发现它非常有用,因此我想强调它的服务功能。

I highly recommend epdb (Extended Python Debugger).

https://bitbucket.org/dugan/epdb

One thing I love about epdb for debugging Django or other Python webservers is the epdb.serve() command. This sets a trace and serves this on a local port that you can connect to. Typical use case:

I have a view that I want to go through step-by-step. I’ll insert the following at the point I want to set the trace.

import epdb; epdb.serve()

Once this code gets executed, I open a Python interpreter and connect to the serving instance. I can analyze all the values and step through the code using the standard pdb commands like n, s, etc.

In [2]: import epdb; epdb.connect()
(Epdb) request
<WSGIRequest
path:/foo,
GET:<QueryDict: {}>, 
POST:<QuestDict: {}>,
...
>
(Epdb) request.session.session_key
'i31kq7lljj3up5v7hbw9cff0rga2vlq5'
(Epdb) list
 85         raise some_error.CustomError()
 86 
 87     # Example login view
 88     def login(request, username, password):
 89         import epdb; epdb.serve()
 90  ->     return my_login_method(username, password)
 91
 92     # Example view to show session key
 93     def get_session_key(request):
 94         return request.session.session_key
 95

And tons more that you can learn about typing epdb help at any time.

If you want to serve or connect to multiple epdb instances at the same time, you can specify the port to listen on (default is 8080). I.e.

import epdb; epdb.serve(4242)

>> import epdb; epdb.connect(host='192.168.3.2', port=4242)

host defaults to ‘localhost’ if not specified. I threw it in here to demonstrate how you can use this to debug something other than a local instance, like a development server on your local LAN. Obviously, if you do this be careful that the set trace never makes it onto your production server!

As a quick note, you can still do the same thing as the accepted answer with epdb (import epdb; epdb.set_trace()) but I wanted to highlight the serve functionality since I’ve found it so useful.


回答 13

我刚刚找到wdb(http://www.rkblog.rk.edu.pl/w/p/debugging-python-code-browser-wdb-debugger/?goback=%2Egde_25827_member_255996401)。它有一个非常漂亮的用户界面/ GUI,带有所有的提示。作者说了有关wdb的内容-

“有些像PyCharm这样的IDE都有自己的调试器。它们提供相似或相同的功能集…但是,要使用它们,您必须使用那些特定的IDE(其中有些是非免费的,或者可能不适用于所有平台)。根据您的需求选择合适的工具。”

以为我会继续下去。

也是有关python调试器的非常有用的文章: https : //zapier.com/engineering/debugging-python-boss/

最后,如果您想在Django中看到调用堆栈的漂亮图形输出,请结帐:https : //github.com/joerick/pyinstrument。只需将pyinstrument.middleware.ProfilerMiddleware添加到MIDDLEWARE_CLASSES,然后在请求URL的末尾添加?profile即可激活分析器。

也可以从命令行或作为模块导入来运行pyinstrument。

I just found wdb (http://www.rkblog.rk.edu.pl/w/p/debugging-python-code-browser-wdb-debugger/?goback=%2Egde_25827_member_255996401). It has a pretty nice user interface / GUI with all the bells and whistles. Author says this about wdb –

“There are IDEs like PyCharm that have their own debuggers. They offer similar or equal set of features … However to use them you have to use those specific IDEs (and some of then are non-free or may not be available for all platforms). Pick the right tool for your needs.”

Thought i’d just pass it on.

Also a very helpful article about python debuggers: https://zapier.com/engineering/debugging-python-boss/

Finally, if you’d like to see a nice graphical printout of your call stack in Django, checkout: https://github.com/joerick/pyinstrument. Just add pyinstrument.middleware.ProfilerMiddleware to MIDDLEWARE_CLASSES, then add ?profile to the end of the request URL to activate the profiler.

Can also run pyinstrument from command line or by importing as a module.


回答 14

在Python代码的相应行中添加import pdb; pdb.set_trace()breakpoint() (形成python3.7)并执行它。执行将以交互式外壳程序停止。在外壳程序中,您可以执行Python代码(即打印变量)或使用以下命令:

  • c 继续执行
  • n 跳到同一功能的下一行
  • s 转到此函数或被调用函数的下一行
  • q 退出调试器/执行

另请参阅:https : //poweruser.blog/setting-a-breakpoint-in-python-438e23fe6b28

Add import pdb; pdb.set_trace() or breakpoint() (form python3.7) at the corresponding line in the Python code and execute it. The execution will stop with an interactive shell. In the shell you can execute Python code (i.e. print variables) or use commands such as:

  • c continue execution
  • n step to the next line within the same function
  • s step to the next line in this function or a called function
  • q quit the debugger/execution

Also see: https://poweruser.blog/setting-a-breakpoint-in-python-438e23fe6b28


回答 15

调试Django代码的最佳选择之一是通过wdb:https : //github.com/Kozea/wdb

wdb可与python 2(2.6、2.7),python 3(3.2、3.3、3.4、3.5)和pypy一起使用。甚至更好的是,可以用在python 3上运行的wdb服务器来调试python 2程序,反之亦然,或者用在第三台计算机的网页内的另一台计算机上运行的调试服务器来调试在计算机上运行的程序!更好的是,现在可以使用Web界面中的代码注入来暂停当前正在运行的python进程/线程。(这需要启用gdb和ptrace)换句话说,它是pdb的非常增强的版本,直接在浏览器中具有不错的功能。

安装并运行服务器,并在代码中添加:

import wdb
wdb.set_trace()

根据作者的说法,主要区别在于pdb

对于那些不了解项目的人,wdb是像pdb这样的python调试器,但是具有光滑的Web前端和许多其他功能,例如:

  • 源语法突出显示
  • 视觉断点
  • 使用jedi的交互式代码完成
  • 持久断点
  • 使用鼠标多线程/多处理支持进行深层对象检查
  • 远程调试
  • 观看表情
  • 在调试器代码版中
  • 流行的Web服务器集成可打破错误
  • 例如,在跟踪过程中发生异常中断(不是事后检验),与werkzeug调试器相反
  • 通过代码注入(在受支持的系统上)破坏当前正在运行的程序

它具有基于浏览器的出色用户界面。使用愉快!:)

One of your best option to debug Django code is via wdb: https://github.com/Kozea/wdb

wdb works with python 2 (2.6, 2.7), python 3 (3.2, 3.3, 3.4, 3.5) and pypy. Even better, it is possible to debug a python 2 program with a wdb server running on python 3 and vice-versa or debug a program running on a computer with a debugging server running on another computer inside a web page on a third computer! Even betterer, it is now possible to pause a currently running python process/thread using code injection from the web interface. (This requires gdb and ptrace enabled) In other words it’s a very enhanced version of pdb directly in your browser with nice features.

Install and run the server, and in your code add:

import wdb
wdb.set_trace()

According to the author, main differences with respect to pdb are:

For those who don’t know the project, wdb is a python debugger like pdb, but with a slick web front-end and a lot of additional features, such as:

  • Source syntax highlighting
  • Visual breakpoints
  • Interactive code completion using jedi
  • Persistent breakpoints
  • Deep objects inspection using mouse Multithreading / Multiprocessing support
  • Remote debugging
  • Watch expressions
  • In debugger code edition
  • Popular web servers integration to break on error
  • In exception breaking during trace (not post-mortem) in contrary to the werkzeug debugger for instance
  • Breaking in currently running programs through code injection (on supported systems)

It has a great browser-based user interface. A joy to use! :)


回答 16

我使用PyCharm和其他调试工具。也有一篇不错的文章集,关于为新手轻松设置这些东西。您可以从这里开始。它介绍了有关Django项目的PDB和GUI调试的一般信息。希望有人能从中受益。

I use PyCharm and different debug tools. Also have a nice articles set about easy set up those things for novices. You may start here. It tells about PDB and GUI debugging in general with Django projects. Hope someone would benefit from them.


回答 17

如果使用Aptana进行Django开发,请观看以下内容:http : //www.youtube.com/watch?v= qQh-UQFltJQ

如果没有,请考虑使用它。

If using Aptana for django development, watch this: http://www.youtube.com/watch?v=qQh-UQFltJQ

If not, consider using it.


回答 18

提到大多数选项。为了打印模板上下文,我为此创建了一个简单的库。参见https://github.com/edoburu/django-debugtools

您可以使用它来打印模板上下文,而无需任何{% load %}构造:

{% print var %}   prints variable
{% print %}       prints all

它使用定制的pprint格式在<pre>标签中显示变量。

Most options are alredy mentioned. To print template context, I’ve created a simple library for that. See https://github.com/edoburu/django-debugtools

You can use it to print template context without any {% load %} construct:

{% print var %}   prints variable
{% print %}       prints all

It uses a customized pprint format to display the variables in a <pre> tag.


回答 19

我发现Visual Studio Code非常适合调试Django应用。标准的python launch.json参数python manage.py与附加的调试器一起运行,因此您可以根据需要设置断点并逐步执行代码。

I find Visual Studio Code is awesome for debugging Django apps. The standard python launch.json parameters run python manage.py with the debugger attached, so you can set breakpoints and step through your code as you like.


回答 20

对于那些可能意外将pdb添加到实时提交中的人,我可以建议#Koobz答案的扩展名:

@register.filter 
def pdb(element):
    from django.conf import settings
    if settings.DEBUG:    
        import pdb
        pdb.set_trace()
    return element

For those that can accidentally add pdb into live commits, I can suggest this extension of #Koobz answer:

@register.filter 
def pdb(element):
    from django.conf import settings
    if settings.DEBUG:    
        import pdb
        pdb.set_trace()
    return element

回答 21

根据我自己的经验,有两种方法:

  1. 使用ipdb,它是像pdb一样的增强调试器。

    import ipdb;ipdb.set_trace()breakpoint() (来自python3.7)

  2. 使用django shell,只需使用下面的命令。在开发新视图时,这非常有帮助。

    python manage.py shell

From my own experience , there are two way:

  1. use ipdb,which is a enhanced debugger likes pdb.

    import ipdb;ipdb.set_trace() or breakpoint() (from python3.7)

  2. use django shell ,just use the command below. This is very helpfull when you are developing a new view.

    python manage.py shell


回答 22

我强烈建议使用PDB。

import pdb
pdb.set_trace()

您可以检查所有变量值,进入函数等等。 https://docs.python.org/2/library/pdb.html

用于检查对数据库的各种请求,响应和命中率。我正在使用django-debug-toolbar https://github.com/django-debug-toolbar/django-debug-toolbar

i highly suggest to use PDB.

import pdb
pdb.set_trace()

You can inspect all the variables values, step in to the function and much more. https://docs.python.org/2/library/pdb.html

for checking out the all kind of request,response and hits to database.i am using django-debug-toolbar https://github.com/django-debug-toolbar/django-debug-toolbar


回答 23

如此处其他文章所述-在代码中设置断点并遍历代码以查看其行为是否符合您的预期,这是学习Django之类的好方法,直到您对所有行为的方式有了很好的了解-以及代码的含义是在做。

为此,我建议使用WingIde。就像其他提到的IDE一样,它们易于使用,易于布局,易于设置断点,可以评估/修改堆栈等。非常适合可视化代码在逐步执行时的工作。我是它的忠实粉丝。

我也使用PyCharm-它具有出色的静态代码分析功能,有时可以帮助您在发现问题之前就发现问题。

如前所述,django-debug-toolbar是必不可少的-https: //github.com/django-debug-toolbar/django-debug-toolbar

尽管不是明确的调试或分析工具,但我最喜欢的工具之一是可从Django Snippets获得的SQL Printing Middleware网址https://djangosnippets.org/snippets/290/

这将显示您的视图已生成的SQL查询。这将使您对ORM的工作以及查询是否有效还是需要重新编写代码(或添加缓存)有一个很好的了解。

我发现它在开发和调试应用程序时密切关注查询性能非常有用。

另一个提示-我稍作修改,只为显示摘要而不显示SQL语句…。因此,在开发和测试时我总是使用它。我还补充说,如果len(connection.queries)大于预定义的阈值,它将显示一个额外的警告。

然后,如果发现不良情况(从性能或查询数量的角度来看),我将重新打开SQL语句的完整显示以查看发生了什么。当您与多个开发人员一起从事大型Django项目时,非常方便。

As mentioned in other posts here – setting breakpoints in your code and walking thru the code to see if it behaves as you expected is a great way to learn something like Django until you have a good sense of how it all behaves – and what your code is doing.

To do this I would recommend using WingIde. Just like other mentioned IDEs nice and easy to use, nice layout and also easy to set breakpoints evaluate / modify the stack etc. Perfect for visualizing what your code is doing as you step through it. I’m a big fan of it.

Also I use PyCharm – it has excellent static code analysis and can help sometimes spot problems before you realize they are there.

As mentioned already django-debug-toolbar is essential – https://github.com/django-debug-toolbar/django-debug-toolbar

And while not explicitly a debug or analysis tool – one of my favorites is SQL Printing Middleware available from Django Snippets at https://djangosnippets.org/snippets/290/

This will display the SQL queries that your view has generated. This will give you a good sense of what the ORM is doing and if your queries are efficient or you need to rework your code (or add caching).

I find it invaluable for keeping an eye on query performance while developing and debugging my application.

Just one other tip – I modified it slightly for my own use to only show the summary and not the SQL statement…. So I always use it while developing and testing. I also added that if the len(connection.queries) is greater than a pre-defined threshold it displays an extra warning.

Then if I spot something bad (from a performance or number of queries perspective) is happening I turn back on the full display of the SQL statements to see exactly what is going on. Very handy when you are working on a large Django project with multiple developers.


回答 24

使用pdbipdb。两者之间的区别在于ipdb支持自动完成。

对于pdb

import pdb
pdb.set_trace()

对于ipdb

import ipdb
ipdb.set_trace()

执行换行n击键,继续c击键。通过使用检查更多选项help(pdb)

use pdb or ipdb. Diffrence between these two is ipdb supports auto complete.

for pdb

import pdb
pdb.set_trace()

for ipdb

import ipdb
ipdb.set_trace()

For executing new line hit n key, for continue hit c key. check more options by using help(pdb)


回答 25

另一个建议。

您可以一起使用鼻子测试pdb,而不是pdb.set_trace()手动插入视图。这样做的好处是,您可以在首次启动时观察错误情况,可能会使用第三方代码。

今天对我来说是个错误。

TypeError at /db/hcm91dmo/catalog/records/

render_option() argument after * must be a sequence, not int

....


Error during template rendering

In template /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/crispy_forms/templates/bootstrap3/field.html, error at line 28
render_option() argument after * must be a sequence, not int
18  
19          {% if field|is_checkboxselectmultiple %}
20              {% include 'bootstrap3/layout/checkboxselectmultiple.html' %}
21          {% endif %}
22  
23          {% if field|is_radioselect %}
24              {% include 'bootstrap3/layout/radioselect.html' %}
25          {% endif %}
26  
27          {% if not field|is_checkboxselectmultiple and not field|is_radioselect %}
28  

      {% if field|is_checkbox and form_show_labels %}

现在,我知道这意味着我烦恼了表单的构造函数,甚至我对哪个字段是个问题也有了很好的认识。但是,我可以使用pdb来查看模板中抱怨的脆性表单吗?

我可以。在鼻子测试中使用–pdb选项:

tests$ nosetests test_urls_catalog.py --pdb

一旦我遇到任何异常(包括正常处理的异常),pdb就会在发生异常的地方停止,我可以四处看看。

  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/forms.py", line 537, in __str__
    return self.as_widget()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/forms.py", line 593, in as_widget
    return force_text(widget.render(name, self.value(), attrs=attrs))
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py", line 513, in render
    options = self.render_options(choices, [value])
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py", line 543, in render_options
    output.append(self.render_option(selected_choices, *option))
TypeError: render_option() argument after * must be a sequence, not int
INFO lib.capture_middleware log write_to_index(http://localhost:8082/db/hcm91dmo/catalog/records.html)
INFO lib.capture_middleware log write_to_index:end
> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py(543)render_options()
-> output.append(self.render_option(selected_choices, *option))
(Pdb) import pprint
(Pdb) pprint.PrettyPrinter(indent=4).pprint(self)
<django.forms.widgets.Select object at 0x115fe7d10>
(Pdb) pprint.PrettyPrinter(indent=4).pprint(vars(self))
{   'attrs': {   'class': 'select form-control'},
    'choices': [[('_', 'any type'), (7, (7, 'type 7', 'RECTYPE_TABLE'))]],
    'is_required': False}
(Pdb)         

现在,很明显,我对crispyfield构造函数的选择参数是因为它是列表中的列表,而不是元组的列表/元组。

 'choices': [[('_', 'any type'), (7, (7, 'type 7', 'RECTYPE_TABLE'))]]

整洁的是,此pdb发生在crispy的代码中,而不是我的,并且我不需要手动插入它。

An additional suggestion.

You can leverage nosetests and pdb together, rather injecting pdb.set_trace() in your views manually. The advantage is that you can observe error conditions when they first start, potentially in 3rd party code.

Here’s an error for me today.

TypeError at /db/hcm91dmo/catalog/records/

render_option() argument after * must be a sequence, not int

....


Error during template rendering

In template /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/crispy_forms/templates/bootstrap3/field.html, error at line 28
render_option() argument after * must be a sequence, not int
18  
19          {% if field|is_checkboxselectmultiple %}
20              {% include 'bootstrap3/layout/checkboxselectmultiple.html' %}
21          {% endif %}
22  
23          {% if field|is_radioselect %}
24              {% include 'bootstrap3/layout/radioselect.html' %}
25          {% endif %}
26  
27          {% if not field|is_checkboxselectmultiple and not field|is_radioselect %}
28  

      {% if field|is_checkbox and form_show_labels %}

Now, I know this means that I goofed the constructor for the form, and I even have good idea of which field is a problem. But, can I use pdb to see what crispy forms is complaining about, within a template?

Yes, I can. Using the –pdb option on nosetests:

tests$ nosetests test_urls_catalog.py --pdb

As soon as I hit any exception (including ones handled gracefully), pdb stops where it happens and I can look around.

  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/forms.py", line 537, in __str__
    return self.as_widget()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/forms.py", line 593, in as_widget
    return force_text(widget.render(name, self.value(), attrs=attrs))
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py", line 513, in render
    options = self.render_options(choices, [value])
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py", line 543, in render_options
    output.append(self.render_option(selected_choices, *option))
TypeError: render_option() argument after * must be a sequence, not int
INFO lib.capture_middleware log write_to_index(http://localhost:8082/db/hcm91dmo/catalog/records.html)
INFO lib.capture_middleware log write_to_index:end
> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/forms/widgets.py(543)render_options()
-> output.append(self.render_option(selected_choices, *option))
(Pdb) import pprint
(Pdb) pprint.PrettyPrinter(indent=4).pprint(self)
<django.forms.widgets.Select object at 0x115fe7d10>
(Pdb) pprint.PrettyPrinter(indent=4).pprint(vars(self))
{   'attrs': {   'class': 'select form-control'},
    'choices': [[('_', 'any type'), (7, (7, 'type 7', 'RECTYPE_TABLE'))]],
    'is_required': False}
(Pdb)         

Now, it’s clear that my choices argument to the crispy field constructor was as it was a list within a list, rather than a list/tuple of tuples.

 'choices': [[('_', 'any type'), (7, (7, 'type 7', 'RECTYPE_TABLE'))]]

The neat thing is that this pdb is taking place within crispy’s code, not mine and I didn’t need to insert it manually.


回答 26

在开发过程中,快速添加

assert False, value

可以帮助诊断视图中或其他任何地方的问题,而无需使用调试器。

During development, adding a quick

assert False, value

can help diagnose problems in views or anywhere else, without the need to use a debugger.


如何检查Django版本

问题:如何检查Django版本

我必须为我们的应用程序使用PythonDjango。所以我有两个版本的Python,分别是2.6和2.7。现在,我已经安装了Django。我可以运行示例应用程序以测试Django成功。但是,如何确定Django使用2.6还是2.7版本以及Django使用什么版本的模块?

I have to use Python and Django for our application. So I have two versions of Python, 2.6 and 2.7. Now I have installed Django. I could run the sample application for testing Django succesfuly. But how do I make sure whether Django uses the 2.6 or 2.7 version and what version of modules Django uses?


回答 0

Django 1.5支持Python 2.6.5和更高版本。

如果您使用的是Linux,并且要检查使用的Python版本,请从命令行运行python -V

如果要检查Django版本,请打开Python控制台并输入

>>> import django
>>> django.VERSION
(2, 0, 0, 'final', 0)

Django 1.5 supports Python 2.6.5 and later.

If you’re under Linux and want to check the Python version you’re using, run python -V from the command line.

If you want to check the Django version, open a Python console and type

>>> import django
>>> django.VERSION
(2, 0, 0, 'final', 0)

回答 1

基本上与bcoughlan的答案相同,但是在这里,它作为可执行命令:

$ python -c "import django; print(django.get_version())"
2.0

Basically the same as bcoughlan’s answer, but here it is as an executable command:

$ python -c "import django; print(django.get_version())"
2.0

回答 2

如果您已安装该应用程序:

$ django-admin.py version
2.0

If you have installed the application:

$ django-admin.py version
2.0

回答 3

转到Django项目主目录并执行以下操作:

./manage.py --version

Go to your Django project home directory and do:

./manage.py --version

回答 4

>>> import django
>>> print(django.get_version())
1.6.1

我正在使用IDLE(Python GUI)。

>>> import django
>>> print(django.get_version())
1.6.1

I am using the IDLE (Python GUI).


回答 5

如果您有点子,也可以

点冻结
它将显示您的所有组件版本,包括Django。

您可以通过grep传递它,以仅获取Django版本。那是,

josh@villaroyale:~/code/djangosite$ pip freeze | grep Django
Django==1.4.3

If you have pip, you can also do a

pip freeze
and it will show your all component version including Django .

You can pipe it through grep to get just the Django version. That is,

josh@villaroyale:~/code/djangosite$ pip freeze | grep Django
Django==1.4.3

回答 6

对于Python

import sys
sys.version

对于Django(如其他人在此处所述):

import django
django.get_version()

仅检查版本的潜在问题是版本会升级,因此代码可能会过时。您要确保’1.7′<‘1.7.1′<‘1.7.5′<‘1.7.10’。普通的字符串比较将在最后一次比较中失败:

>>> '1.7.5' < '1.7.10'
False

解决方案是使用distutils中的StrictVersion

>>> from distutils.version import StrictVersion
>>> StrictVersion('1.7.5') < StrictVersion('1.7.10')
True

For Python:

import sys
sys.version

For Django (as mentioned by others here):

import django
django.get_version()

The potential problem with simply checking the version, is that versions get upgraded and so the code can go out of date. You want to make sure that ‘1.7’ < ‘1.7.1’ < ‘1.7.5’ < ‘1.7.10’. A normal string comparison would fail in the last comparison:

>>> '1.7.5' < '1.7.10'
False

The solution is to use StrictVersion from distutils.

>>> from distutils.version import StrictVersion
>>> StrictVersion('1.7.5') < StrictVersion('1.7.10')
True

回答 7

正如您所说的,您有两个版本的python,我假设它们位于不同的虚拟环境(例如venv)或conda 环境中

当您安装django时,可能仅在一种环境中。可能有两个不同版本的django,每个版本的python都有一个。

在Unix / Mac终端中,您可以如下检查python版本:

$ python --version

如果您想知道来源:

$ which python

并检查django的版本:

$ python -m django --version

As you say you have two versions of python, I assume they are in different virtual environments (e.g. venv) or perhaps conda environments.

When you installed django, it was likely in only one environment. It is possible that you have two different versions of django, one for each version of python.

In from a Unix/Mac terminal, you can check your python version as follows:

$ python --version

If you want to know the source:

$ which python

And to check the version of django:

$ python -m django --version

回答 8

有多种获取Django版本的方法。您可以根据需要使用以下给出的任何一种。

注意: 如果您在虚拟环境中工作,请加载python环境


终端命令

  1. python -m django --version
  2. django-admin --version 要么 django-admin.py version
  3. ./manage.py --version 要么 python manage.py --version
  4. pip freeze | grep Django
  5. python -c "import django; print(django.get_version())"
  6. python manage.py runserver --version

Django Shell命令

  1. import django django.get_version() 要么 django.VERSION
  2. from django.utils import version version.get_version() 要么 version.get_complete_version()
  3. import pkg_resources pkg_resources.get_distribution('django').version

(如果您有某种更正或想添加更多相关信息,请随意修改此答案。)

There are various ways to get the Django version. You can use any one of the following given below according to your requirements.

Note: If you are working in a virtual environment then please load your python environment


Terminal Commands

  1. python -m django --version
  2. django-admin --version or django-admin.py version
  3. ./manage.py --version or python manage.py --version
  4. pip freeze | grep Django
  5. python -c "import django; print(django.get_version())"
  6. python manage.py runserver --version

Django Shell Commands

  1. import django django.get_version() OR django.VERSION
  2. from django.utils import version version.get_version() OR version.get_complete_version()
  3. import pkg_resources pkg_resources.get_distribution('django').version

(Feel free to modify this answer, if you have some kind of correction or you want to add more related information.)


回答 9

要使用Python Shell进行检查,请执行以下操作。

>>>from django import get_version
>>> get_version()

如果您希望在Unix / Linux shell中使用一行来完成此操作,请执行

python -c 'import django; print(django.get_version())'

开发应用程序后,即可使用以下方法直接检查版本。

python manage.py runserver --version

For checking using a Python shell, do the following.

>>>from django import get_version
>>> get_version()

If you wish to do it in Unix/Linux shell with a single line, then do

python -c 'import django; print(django.get_version())'

Once you have developed an application, then you can check version directly using the following.

python manage.py runserver --version

回答 10

django-admin --version
python manage.py --version
pip freeze | grep django
django-admin --version
python manage.py --version
pip freeze | grep django

回答 11

Django将使用PYTHONPATH环境变量指定的Python版本。您可以echo $PYTHONPATH在外壳中使用以确定要使用的版本。

Django使用的模块版本将是PYTHONPATH指定的Python版本下安装的模块版本。

Django will use the version of Python specified by the PYTHONPATH environment variable. You can use echo $PYTHONPATH in a shell to determine which version will be used.

The module versions used by Django will be the module versions installed under the version of Python specified by PYTHONPATH.


回答 12

pip list在LINUX TERMINAL上运行,并在列表中找到Django及其版本

pip freeze在Windows上的cmd上 运行

run pip list on LINUX TERMINAL and find Django and its version on list

run pip freeze on cmd on Windows


回答 13

您也可以不用Python就可以做到。只需在Django目录中输入以下内容即可:

cat __init__.py | grep VERSION

你会得到类似的东西:

VERSION = (1, 5, 5, 'final', 0)

You can do it without Python too. Just type this in your Django directory:

cat __init__.py | grep VERSION

And you will get something like:

VERSION = (1, 5, 5, 'final', 0)

回答 14

Django中有一个未记录的utils版本模块

https://github.com/django/django/blob/master/django/utils/version.py

有了它,您可以将正常版本作为字符串或详细版本元组获取:

>>> from django.utils import version
>>> version.get_version()
... 1.9
>>> version.get_complete_version()
... (1, 9, 0, 'final', 0)

There is an undocumented utils versions module in django

https://github.com/django/django/blob/master/django/utils/version.py

With that you can get the normal version as string or a detailed version tuple:

>>> from django.utils import version
>>> version.get_version()
... 1.9
>>> version.get_complete_version()
... (1, 9, 0, 'final', 0)

回答 15

Django版本或任何其他软件包版本

打开终端或命令提示符

类型

pip show django

要么

pip3 show django

您可以找到任何软件包版本…
示例

pip show tensorflow

pip show numpy 

等等….

Django version or any other package version

open the terminal or command prompt

type

pip show django

or

pip3 show django

you can find any package version…
example

pip show tensorflow

pip show numpy 

etc….


回答 16

输入您的CMD或终端:

python -m django --version

Type in your CMD or terminal:

python -m django --version

回答 17

我认为最Python化的方式是:

>>> import pkg_resources; 
>>> pkg_resources.get_distribution('django').version
'1.8.4'

这直接与setup.py相关联: https //github.com/django/django/blob/master/setup.py#L37

这绝对是获得ANY软件包版本号的最佳方法!

也有 distutils

>>> from distutils.version import LooseVersion, StrictVersion
>>> LooseVersion("2.3.1") < LooseVersion("10.1.2")
True
>>> StrictVersion("2.3.1") < StrictVersion("10.1.2")
True
>>> StrictVersion("2.3.1") > StrictVersion("10.1.2")
False

至于python版本,我同意@jamesdradbury

>>> import sys
>>> sys.version
'3.4.3 (default, Jul 13 2015, 12:18:23) \n[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)]'

捆绑在一起:

>>> StrictVersion((sys.version.split(' ')[0])) > StrictVersion('2.6')
True

I thought the most pythonic way was:

>>> import pkg_resources; 
>>> pkg_resources.get_distribution('django').version
'1.8.4'

This ties directly into setup.py: https://github.com/django/django/blob/master/setup.py#L37

Its definitely the best way to get the version number of ANY package!

Also there is distutils

>>> from distutils.version import LooseVersion, StrictVersion
>>> LooseVersion("2.3.1") < LooseVersion("10.1.2")
True
>>> StrictVersion("2.3.1") < StrictVersion("10.1.2")
True
>>> StrictVersion("2.3.1") > StrictVersion("10.1.2")
False

As for the python version, i agree with @jamesdradbury

>>> import sys
>>> sys.version
'3.4.3 (default, Jul 13 2015, 12:18:23) \n[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)]'

Tying it all together:

>>> StrictVersion((sys.version.split(' ')[0])) > StrictVersion('2.6')
True

回答 18

如果要进行Django版本比较,可以使用django-nine(pip install django-nine)。例如,如果您的环境中安装的Django版本是1.7.4,则以下内容将适用。

from nine import versions

versions.DJANGO_1_7 # True
versions.DJANGO_LTE_1_7 # True
versions.DJANGO_GTE_1_7 # True
versions.DJANGO_GTE_1_8 # False
versions.DJANGO_GTE_1_4 # True
versions.DJANGO_LTE_1_6 # False

If you want to make Django version comparison, you could use django-nine (pip install django-nine). For example, if Django version installed in your environment is 1.7.4, then the following would be true.

from nine import versions

versions.DJANGO_1_7 # True
versions.DJANGO_LTE_1_7 # True
versions.DJANGO_GTE_1_7 # True
versions.DJANGO_GTE_1_8 # False
versions.DJANGO_GTE_1_4 # True
versions.DJANGO_LTE_1_6 # False

回答 19

在Python Shell中输入以下命令

import django
django.get_version()

Type the following command in Python shell

import django
django.get_version()

回答 20

Django 1.0之后,您可以执行此操作

$ django-admin --version
1.11.10

After django 1.0 you can just do this

$ django-admin --version
1.11.10

回答 21

您可以通过在shell提示符中运行以下命令来获取Django版本

python -m django –version

如果安装了Django,则应该看到该版本,否则将收到错误消息,提示“没有名为django的模块”。

You can get django version by running the following command in a shell prompt

python -m django –version

If Django is installed, you should see the version otherwise you’ll get an error telling “No module named django”.


回答 22

您可以导入django,然后按如下所示键入print语句,以了解django的版本,即安装在系统上的版本:

>>> import django
>>> print(django.get_version())
2.1

you can import django and then type print statement as given below to know the version of django i.e. installed on your system:

>>> import django
>>> print(django.get_version())
2.1

回答 23

Django版本支持的Python版本

Django version     Python versions
1.0                2.3, 2.4, 2.5, 2.6
1.1                2.3, 2.4, 2.5, 2.6
1.2                2.4, 2.5, 2.6, 2.7
1.3                2.4, 2.5, 2.6, 2.7
1.4                2.5, 2.6, 2.7
1.5                2.6.5, 2.7 and 3.2.3, 3.3 (experimental)
1.6                2.6.5, 2.7 and 3.2.3, 3.3
1.11               2.7, 3.4, 3.5, 3.6, 3.7 (added in 1.11.17)
2.0                3.4, 3.5, 3.6, 3.7
2.1, 2.2           3.5, 3.6, 3.7

要验证Python是否可以看到Django,请在您的shell中键入python。然后在Python提示符下,尝试导入Django:

>>> import django
>>> print(django.get_version())
2.1
>>> django.VERSION
(2, 1, 4, 'final', 0)

Python version supported by Django version

Django version     Python versions
1.0                2.3, 2.4, 2.5, 2.6
1.1                2.3, 2.4, 2.5, 2.6
1.2                2.4, 2.5, 2.6, 2.7
1.3                2.4, 2.5, 2.6, 2.7
1.4                2.5, 2.6, 2.7
1.5                2.6.5, 2.7 and 3.2.3, 3.3 (experimental)
1.6                2.6.5, 2.7 and 3.2.3, 3.3
1.11               2.7, 3.4, 3.5, 3.6, 3.7 (added in 1.11.17)
2.0                3.4, 3.5, 3.6, 3.7
2.1, 2.2           3.5, 3.6, 3.7

To verify that Django can be seen by Python, type python from your shell. Then at the Python prompt, try to import Django:

>>> import django
>>> print(django.get_version())
2.1
>>> django.VERSION
(2, 1, 4, 'final', 0)

回答 24

只需键入python -m django --version 或键入pip freeze即可查看已安装模块的所有版本,包括Django。

Simply type python -m django --version or type pip freeze to see all the versions of installed modules including Django.