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.
KeyError at /mypage/'REMOTE_ADDR'RequestMethod: GETRequest URL: http://mywebsite.com/mypage/DjangoVersion:1.2.4ExceptionType:KeyErrorExceptionValue:'REMOTE_ADDR'ExceptionLocation:/mysite/homepage/views.py in home, line 9PythonExecutable:/usr/bin/pythonPythonVersion:2.6.6PythonPath:['/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,2Jan201120:42:50-0600
# 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
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)
# In a view or a middleware where the `request` object is availablefrom ipware import get_client_ip
ip, is_routable = get_client_ip(request)if ip isNone:# Unable to get the client's IP addresselse:# We got the client's IP addressif is_routable:# The client's IP address is publicly routable on the Internetelse:# 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.'))
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
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
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 beginningwhile(len(proxies)>0and
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 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.
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.
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.
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:
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','notin x_forwarded_for:ifnot 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):continueelifnot is_valid_ip(ip):continueelse:
ip_address = ip
breakifnot ip_address:
x_real_ip = request.META.get('HTTP_X_REAL_IP','')if x_real_ip:ifnot x_real_ip.startswith(PRIVATE_IPS_PREFIX)and is_valid_ip(x_real_ip):
ip_address = x_real_ip.strip()ifnot ip_address:
remote_addr = request.META.get('REMOTE_ADDR','')if remote_addr:ifnot remote_addr.startswith(PRIVATE_IPS_PREFIX)and is_valid_ip(remote_addr):
ip_address = remote_addr.strip()ifnot 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
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')
]
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.
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.
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)
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.
classPurchPurchaseAccount(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)classMeta:
db_table = u'purch_purchase_account'
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:
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.
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.
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.
classCity(models.Model):# define model fields for a cityclassProperty(models.Model):
city = models.ForeignKey(City, on_delete = models.CASCADE)# define model fields for a property
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.
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模型,像这样
classPerson(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=20)def __str__(self):return self.id+self.name
然后,公司模型如下所示
classCompanies(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)
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.
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.”
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)
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'isnot recognized as an internal or external command,
operable program or batch file.
C:\Python34>lib\site-packages\pip install Django'lib\site-packages\pip'isnot recognized as an internal or external command,
operable program or batch file.
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%
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.
As of now, version 3.7.3 I had a little bit of an issue with getting the right system variable.
Try this:
Type ‘start %appdata%’ in cmd.
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.
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.
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.
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.
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.
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.
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.
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.
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对我不起作用。
WorkaroundCopy 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\DLLsThen open a new DOS command shell prompt.
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.
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>
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.
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.
classTravel(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()
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.
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.
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
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?
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:
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.
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”.
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)
“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).
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)
classArticle(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(max_length=100)
如果您想使用标题作为标题,django有一个简单的函数称为 slugify
from django.template.defaultfilters import slugify
classArticle(models.Model):
title = models.CharField(max_length=100)def slug(self):return slugify(self.title)
如果需要唯一性,请添加unique=True子弹字段。
例如,从前面的示例中:
classArticle(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(max_length=100, unique=True)
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
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:
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?
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.
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
@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.
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).
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
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'isnot defined
======================================================================>/Users/tom/github/django-pdb/testproject/testapp/tests.py(16)test_error()-> one_plus_one = four
(Pdb)
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…
pip install django-pdb
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.
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:
Your breakpoint is hit, you can view/change the variables as easy as debugging C#/C++ programs.
That’s all :)
If you want to debug Django using PTVS, you need to do the following:
In Project settings – General tab, set “Startup File” to “manage.py”, the entry point of the Django program.
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.
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.
From my perspective, we could break down common code debugging tasks into three distinct usage patterns:
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.
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.
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.
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.
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.
“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.”
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.
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
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! :)
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.
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
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.
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.
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
1819{%if field|is_checkboxselectmultiple %}20{% include 'bootstrap3/layout/checkboxselectmultiple.html'%}21{% endif %}2223{%if field|is_radioselect %}24{% include 'bootstrap3/layout/radioselect.html'%}25{% endif %}2627{%ifnot field|is_checkboxselectmultiple andnot field|is_radioselect %}28{%if field|is_checkbox and form_show_labels %}
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)
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.
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?
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:
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:
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.
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.