Django database query: How to get object by id? - django

Django automatically creates an id field as primary key.
Now I need to get the object by this id.
object = Class.objects.filter()
How to write this filter?

If you want to get an object, using get() is more straightforward:
obj = Class.objects.get(pk=this_object_id)

I got here for the same problem, but for a different reason:
Class.objects.get(id=1)
This code was raising an ImportError exception. What was confusing me was that the code below executed fine and returned a result set as expected:
Class.objects.all()
Tail of the traceback for the get() method:
File "django/db/models/loading.py", line 197, in get_models
self._populate()
File "django/db/models/loading.py", line 72, in _populate
self.load_app(app_name, True)
File "django/db/models/loading.py", line 94, in load_app
app_module = import_module(app_name)
File "django/utils/importlib.py", line 35, in import_module
__import__(name)
ImportError: No module named myapp
Reading the code inside Django's loading.py, I came to the conclusion that my settings.py had a bad path to my app which contains my Class model definition. All I had to do was correct the path to the app and the get() method executed fine.
Here is my settings.py with the corrected path:
INSTALLED_APPS = (
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
# ...
'mywebproject.myapp',
)
All the confusion was caused because I am using Django's ORM as a standalone, so the namespace had to reflect that.

You can also use get_object_or_404 django shortcut. It raises a 404 error if object is not found.

You can use:
objects_all=Class.objects.filter(filter_condition="")
This will return a query set even if it gets one object.
If you need exactly one object use:
obj=Class.objects.get(conditon="")

You can also do:
obj = ClassModel.get_by_id(object_id)
This works, but there may I'm not sure if it's supported in Django 2.

In case you don't have some id, e.g., mysite.com/something/9182301, you can use get_object_or_404 importing by from django.shortcuts import get_object_or_404.
Use example:
def myFunc(request, my_pk):
my_var = get_object_or_404(CLASS_NAME, pk=my_pk)

Related

Is there a workaround for Django's `ModelDoesNotExist` error in a situation like this?

So I get a ModelDoesNotExist error when I run manage.py runserver because in a file in my directory, I make a query to a table which has not been populated yet.
def __init__(self):
self.spotify_object = SocialToken.objects.get(account__provider="spotify")
The above is a class instantiated to perform some sort of authentication and the SocialToken table gets populated only after I login. Now, I was wondering if there was a way to escape the error by triggering this part of the code only after I login? I only use the class in an endpoint, and during that period, the table would have been populated but the fact that it is not populated before running the server is causing a DoesNotExist error. Is there a solution to this?
Traceback
File "C:\Users\Kwaku Biney\Desktop\sparison-1\project\Sparison\views.py", line 4, in <module>
from .authentication import SparisonCacheHandler
File "C:\Users\Kwaku Biney\Desktop\sparison-1\project\Sparison\authentication.py", line 43, in
<module>
cache_handler = SparisonCacheHandler() ,
File "C:\Users\Kwaku Biney\Desktop\sparison-1\project\Sparison\authentication.py", line 25,
in __init__
self.spotify_object = SocialToken.objects.get(account__provider="spotify")
File "C:\Users\Kwaku Biney\Desktop\sparison-1\project\venv\lib\site-
packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\Kwaku Biney\Desktop\sparison-1\project\venv\lib\site-
packages\django\db\models\query.py", line 429, in get
raise self.model.DoesNotExist(
allauth.socialaccount.models.DoesNotExist: SocialToken matching query does not exist.
In my views.py, I import the class which has the query and the error comes up.
There are two ways to avoid the DoesNotExist Error.
A) Use .filter() instead of .get()
Filtering leads to an empty queryset when the search comes up empty.
def __init__(self):
self.spotify_object = SocialToken.objects.filter(account__provider="spotify")
B) Use get_object_or_404() instead of .get()
This is a built-in function by django:
Calls get() on a given model manager, but it raises Http404 instead of the model’s DoesNotExist exception.
Django Documentation
def __init__(self):
self.spotify_object = SocialToken.objects.get_object_or_404(account__provider="spotify")
Hope I could help you. Have a nice day.

Log warning from Selenium on Django [duplicate]

Whenever I try to construct a string based on self.live_server_url, I get python TypeError messages. For example, I've tried the following string constructions (form 1 & 2 below), but I experience the same TypeError. My desired string is the Live Server URL with "/lists" appended. NOTE: the actual test does succeed to create a server and I can manually access the server, and more specifically, I can manually access the exact URL that I'm trying to build programmatically (e.g. 'http://localhost:8081/lists').
TypeErrors occur with these string constructions.
# FORM 1
lists_live_server_url = '%s%s' % (self.live_server_url, '/lists')
# FORM 2
lists_live_server_url = '{0}{1}'.format(self.live_server_url, '/lists')
self.browser.get(lists_live_server_url)
There is no python error with this form (nothing appended to string), albeit my test fails (as I would expect since it isn't accessing /lists).
self.browser.get(self.live_server_url)
Here is the python error that I'm getting.
/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/bin/python3.4 /Applications/PyCharm.app/Contents/helpers/pycharm/django_test_manage.py test functional_tests.lists_tests.LiveNewVisitorTest.test_can_start_a_list_and_retrieve_it_later /Users/myusername/PycharmProjects/mysite_proj
Testing started at 11:55 AM ...
Creating test database for alias 'default'...
Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/wsgiref/handlers.py", line 137, in run
self.result = application(self.environ, self.start_response)
File "/usr/local/lib/python3.4/site-packages/django/test/testcases.py", line 1104, in __call__
return super(FSFilesHandler, self).__call__(environ, start_response)
File "/usr/local/lib/python3.4/site-packages/django/core/handlers/wsgi.py", line 189, in __call__
response = self.get_response(request)
File "/usr/local/lib/python3.4/site-packages/django/test/testcases.py", line 1087, in get_response
return self.serve(request)
File "/usr/local/lib/python3.4/site-packages/django/test/testcases.py", line 1099, in serve
return serve(request, final_rel_path, document_root=self.get_base_dir())
File "/usr/local/lib/python3.4/site-packages/django/views/static.py", line 54, in serve
fullpath = os.path.join(document_root, newpath)
File "/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/posixpath.py", line 82, in join
path += b
TypeError: unsupported operand type(s) for +=: 'NoneType' and 'str'
Am I unknowingly attempting to modify the live_server_url, which is leading to these TypeErrors? How could I programmatically build a string of live_server_url + "/lists"?
Here is the test that I am attempting...
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from django.test import LiveServerTestCase
class LiveNewVisitorTest(LiveServerTestCase):
def setUp(self):
self.browser = webdriver.Chrome()
self.browser.implicitly_wait(3)
def tearDown(self):
self.browser.close()
def test_can_start_a_list_and_retrieve_it_later(self):
#self.browser.get('http://localhost:8000/lists')
#self.browser.get('http://www.google.com')
#lists_live_server_url = '%s%s' % (self.live_server_url, '/lists')
#lists_live_server_url = '{0}{1}'.format(self.live_server_url, '/lists')
lists_live_server_url = self.live_server_url
self.browser.get(lists_live_server_url)
self.assertIn('To-Do', self.browser.title)
header_text = self.browser.find_element_by_tag_name('h1').text
self.assertIn('To-Do', header_text)
See this discussion on Reddit featuring the same error Traceback.
Basically, this is not a problem with anything within the Selenium tests but rather with your project's static file configuration.
From your question, I believe the key line within the Traceback is:
File "/usr/local/lib/python3.4/site-packages/django/views/static.py", line 54, in serve
fullpath = os.path.join(document_root, newpath)
This line indicates that an unsuccessful os.path.join is being attempted within django.views.static.
Set STATIC_ROOT in your project's settings.pyfile and you should be good.
Use StaticLiveServerTestCase instead may help

Django AttributeError: 'str' object has no attribute '_default_manager'

The following error seems to occur randomly on my live server (i.e. through apache mod_wsgi) but never in development (i.e. localhost python manage.py runserver).
Note this happens infrequently and is not something that can be reproduced easily or each time a specific url is accessed.
I have seen various answers posted both here on SO and on google but there does not seem to be any definitive reason as to why this error occurs. Maybe this is because the error is fairly generic but the most common answer seems to be due to circular import errors. Another answer I've seen is that model FK field references have not been the correct case (e.g. applabel.model instead of applabel.Model) but all my model FK fields are correct.
The cause of the error seems to point to one of my admin.py files. This file did originally import custom form classes from a forms.py file. Both the admin.py file and forms.py file imported the same models from a models.py file. Therefore I moved the form classes to the admin.py file in case there was a circular reference occurring here but I still occasionally get these errors.
Could anyone shed any light as to why this error occurs and why so randomly? I always ensure the relevant services are restarted after a code update.
Traceback is:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 101, in get_response
request.path_info)
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py", line 250, in resolve
for pattern in self.url_patterns:
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py", line 279, in _get_url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py", line 274, in _get_urlconf_module
self._urlconf_module = import_module(self.urlconf_name)
File "/usr/local/lib/python2.7/dist-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/myproject/urls.py", line 6, in <module>
admin.autodiscover()
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/__init__.py", line 26, in autodiscover
import_module('%s.admin' % app)
File "/usr/local/lib/python2.7/dist-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
File "/myproject/myapps/app/admin.py", line 61, in <module>
class CardAdminForm(forms.ModelForm):
File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py", line 205, in __new__
opts.exclude, opts.widgets, formfield_callback)
File "/usr/local/lib/python2.7/dist-packages/django/forms/models.py", line 159, in fields_for_model
formfield = f.formfield(**kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/related.py", line 913, in formfield
'queryset': self.rel.to._default_manager.using(db).complex_filter(self.rel.limit_choices_to),
AttributeError: 'str' object has no attribute '_default_manager'
Packages and versions
Warning: cannot find svn location for pymssql==2.0.0b1-dev-20111019
Warning: cannot find svn location for distribute==0.6.24dev-r0
Django==1.3.3
GnuPGInterface==0.3.2
Landscape-Client==12.05
PAM==0.4.2
PIL==1.1.7
Twisted-Core==11.1.0
apt-xapian-index==0.44
argparse==1.2.1
chardet==2.0.1
command-not-found==0.2.44
## FIXME: could not find svn URL in dependency_links for this package: distribute==0.6.24dev-r0
django-debug-toolbar==0.9.4
django-rosetta==0.6.8
httplib2==0.7.2
iotop==0.4.4
keyring==0.7.1
language-selector==0.1
launchpadlib==1.9.12
lazr.restfulclient==0.12.0
lazr.uri==1.0.3
mercurial==2.0.2
oauth==1.0.1
psycopg2==2.4.5
pyOpenSSL==0.12
pycrypto==2.4.1
## FIXME: could not find svn URL in dependency_links for this package:pymssql==2.0.0b1-dev-20111019
pyserial==2.5
python-apt==0.8.3ubuntu7
python-debian==0.1.21ubuntu1
reportlab==2.5
simplejson==2.3.2
ufw==0.31.1-1
wadllib==1.3.0
wsgiref==0.1.2
xlwt==0.7.4
zope.interface==3.6.1
Database: Postgresql 9.1.5
CardAdmin and CardAdminForm:
class CardAdmin(admin.ModelAdmin):
form = CardAdminForm
raw_id_fields = ('cust', 'acc', 'vehicle', 'driver')
list_display = ('id', 'pan', 'name', 'expiry', 'created', 'modified')
list_filter = ('status', )
search_fields = ['id', 'pan']
admin.site.register(Card, CardAdmin)
class CardAdminForm(forms.ModelForm):
"""
A Form for Cards (Admin console)
"""
def __init__(self, *args, **kwargs):
super(CardAdminForm, self).__init__(*args, **kwargs)
self.fields['cust'].required = True
self.fields['acc'].required = True
self.fields['name'].required = True
self.fields['code'].widget = forms.PasswordInput()
self.fields['code'].max_length = 6
class Meta:
model = Card
fields = (
'cust',
'name',
'acc',
'no',
'code',
'type',
'status',
'address_1',
'address_2',
'zip',
'city',
'country',
'phone_no',
'expiry',
'vehicle',
'driver'
)
def save(self, commit=True):
# Save some additional data.
form_instance = super(CardAdminForm, self).save(commit=False)
cleaned_data = self.cleaned_data
form_instance.pan = '%s%s%s'\
% (
cleaned_data['acc'].iso.number,
cleaned_data['acc'].number,
cleaned_data['no']
)
if commit:
form_instance.save()
return form_instance
Quick note for people still finding this old issue: This case can also be caused by a ForeignKey/ManyToMany/OnetoOne that uses a string as reference that is invalid (eg: not correctly pointing to a model).
I was updating/refactoring a project and ran into this. Turned out it was just a typo.
Kinda weird django doesn't notify clearly it cannot resolve the string, could be because other apps confused it.
_default_manager is the attribute on a model that holds the (surprise, surprise) default manager for that model. Django uses this all over the place, especially in the admin, to return querysets for ModelAdmins.
So the error is telling you that somewhere, you've passed a string where a model class or instance was expected. It tries to call _default_manager on the string, and fails, obviously.
However, since the error comes in Django code, in particular when referencing self.rel.to on an instance, I can only assume that you or some third-party whose code you are utilizing has made some pretty integral and monumental changes to something. This is not how the stock code should behave.
The solution to my problem seems to have been resolved by looking at the following links:
Getting the “str” has no property “_default_manager” on a Django app just on startup
and:
Django Ticket 10405 Comment 11
Technically Chris Pratt's answer is absolutely correct and a very good explanation but nowhere in my code could I find an instance that would be causing this error.
The error occurred randomly but the source of this error was mostly being triggered by a server monitoring system requesting the base url (/) for my website (i.e. full HTTP page request). I can only assume the monitoring system uses something like the wget command to make this check so I used this command to test the base url for my website.
Occasionally this command would return a 200 OK response but on most occasions this would return a 500 Internal Server Error response, even though I could access the website fine from a browser. It seems also that a 500 Internal Server Error response would always occur immediately after restarting Apache.
I'm still a bit puzzled as to the exact cause and randomness of this error, discussions I've seen point to a possible bug in the Django framework but this doesn't happen in other websites using the same set up I have implemented here. Reading through the comments in the 2nd link above, it seems to be that a similar code layout has been used as that in my question above (only happens in production using Apache/mod_wsgi, ModelForms used for admin section, using quoted FK references in models).
As mentioned in the above links the solution is to insert:
from django.db.models.loading import cache as model_cache
if not model_cache.loaded:
model_cache.get_models()
before:
admin.autodiscover()
in the base urls.py file.
Hope this helps others that may stumble upon this weird issue. I've had no errors since making the above code addition.
I ran in to this error message because I did not correctly specify the model in the meta class of a factory
class FooBarFactory(factory.django.DjangoModelFactory):
class Meta:
model = 'foobar' # <-- must be 'myapp.foobar'
File "/home/lb/.local/lib/python3.6/site-packages/django/db/models/fields/related.py", line 1673, in formfield
'queryset': self.remote_field.model._default_manager.using(using),
AttributeError: 'str' object has no attribute '_default_manager'
In my module there was an incorrect code with a String:
Error:
tags = models.ManyToManyField('Tag', blank=True)
Correct:
tags = models.ManyToManyField(Tag, blank=True)
I have not created the class Tag
I got a similar error when I did:
from people.models import Quote
quote = models.ManyToManyField(
"Quote",
blank=True,
verbose_name=_("Quotes"),
help_text=_("Select quotes"),
default=None,
related_name="people_quotes"
)
But when I removed the quotes around the referenced model "Quote", the error went away.
from people.models import Quote
quote = models.ManyToManyField(
Quote,
blank=True,
verbose_name=_("Quotes"),
help_text=_("Select quotes"),
default=None,
related_name="people_quotes"
)

(Obviously) Not possible to append to tuple. Why does django userena test do it?

INSTALLED_APPS in django is obviously a tuple and therefore immutable.
Why does django-userena try to append a module to it at runtime?
Reference userena/tests/profiles/test.py
from django import test
class ProfileTestCase(test.TestCase):
""" A custom TestCase that loads the profile application for testing purposes """
def _pre_setup(self):
# Add the models to the db.
self._original_installed_apps = list(settings.INSTALLED_APPS)
settings.INSTALLED_APPS.append('userena.tests.profiles')
loading.cache.loaded = False
call_command('syncdb', interactive=False, verbosity=0)
# Call the original method that does the fixtures etc.
super(ProfileTestCase, self)._pre_setup()
def _post_teardown(self):
# Call the original method.
super(ProfileTestCase, self)._post_teardown()
# Restore the settings.
settings.INSTALLED_APPS = self._original_installed_apps
loading.cache.loaded = False
And obviously, when I run the unit tests with userena, I get errors such as:-
======================================================================
ERROR: test_can_view_profile (userena.tests.models.BaseProfileModelTest)
Test if the user can see the profile with three type of users.
----------------------------------------------------------------------
Traceback (most recent call last):
File "./django-trunk/django/test/testcases.py", line 499, in __call__
self._pre_setup()
File "./_thirdparty/django-userena/userena/tests/profiles/test.py", line 11, in _pre_setup
settings.INSTALLED_APPS.append('userena.tests.profiles')
AttributeError: 'tuple' object has no attribute 'append'
======================================================================
ERROR: test_get_full_name_or_username (userena.tests.models.BaseProfileModelTest)
Test if the full name or username are returned correcly
----------------------------------------------------------------------
Traceback (most recent call last):
File "./django-trunk/django/test/testcases.py", line 499, in __call__
self._pre_setup()
File "./_thirdparty/django-userena/userena/tests/profiles/test.py", line 11, in _pre_setup
settings.INSTALLED_APPS.append('userena.tests.profiles')
AttributeError: 'tuple' object has no attribute 'append'
How do I solve this problem?
I think this:
self._original_installed_apps = list(settings.INSTALLED_APPS)
settings.INSTALLED_APPS.append('userena.tests.profiles')
Should be
self._original_installed_apps = list(settings.INSTALLED_APPS)
settings.INSTALLED_APPS += ('userena.tests.profiles',)
Looks like a bug to me.
INSTALLED_APPS is a tuple by default but can be changed to a list. The author of that app probably did change that for themselves, wrote the tests and didn't realize that it won't work for people who have INSTALLED_APPS as a tuple. You can most likely fix the problem by changing your settings.INSTALLED_APPS to a list.
Btw, there are better ways how to override settings.

django ViewDoesNotExist

I'm getting a weird error and I can't track it down. The stack trace doesn't give any clue as to the location of the error either. It's just giving me the standard urlresolvers.py ViewDoesNotExist exception. Here is the error message:
Could not import myapp.myview.views. Error was: No module named model
At first I thought I forgot to put an "s" on models somewhere in my code, but after a search of the entire codebase, that is not the case.
Here's the trackback:
File "C:\Python25\Lib\site-packages\django\core\handlers\base.py" in get_response
91. request.path_info)
File "C:\Python25\Lib\site-packages\django\core\urlresolvers.py" in resolve
216. sub_match = pattern.resolve(new_path)
File "C:\Python25\Lib\site-packages\django\core\urlresolvers.py" in resolve
216. sub_match = pattern.resolve(new_path)
File "C:\Python25\Lib\site-packages\django\core\urlresolvers.py" in resolve
216. sub_match = pattern.resolve(new_path)
File "C:\Python25\Lib\site-packages\django\core\urlresolvers.py" in resolve
123. return self.callback, args, kwargs
File "C:\Python25\Lib\site-packages\django\core\urlresolvers.py" in _get_callback
132. raise ViewDoesNotExist("Could not import %s. Error was: %s" % (mod_name, str(e)))
Exception Value: Could not import myapp.myview.views. Error was: No module named model
From what you've posted, it seems like the error is in myapp.myview.views.
You already mentioned looking for misspellings of "models", which is good. You might also try asking Django to validate your models to ensure that they are properly importable (run this in your Django project root):
python manage.py validate
Beyond that, just keep following the imports in myapp.myview.views until you see something odd. You can check to see if everything is properly importable by opening a shell:
python manage.py shell
And attempting to import and/or try things from there.
Beyond that, someone may be able to assist you more if you post the full traceback. Good luck!
I have been having the same error, and I solved my problem. If you have a forms.py, ensure that all your forms fields are valid. For some reason, if your forms.py file has form field errors, then it causes this exception.
So myapp/myview/views.py imports model and fails. What does the import statement look like?
You can check to see if everything is properly importable by opening a shell:
python manage.py shell
That creates a running environment just as the same as where there is request and response. I believe you can get light on this question if you do it, because I have ever got it and managed it.
Good luck with you.
For me, the view that couldn't be imported had a bad decorator call. Try commenting out the decorator.
##login_required(login_url=reverse('bad!'))
def view_name(request):
Specifically the reverse is failing. Changing it to
#login_required(login_url='http://usatoday.com')
def view_name(request):
works. But, strangely enough, this one url doesn't work:
#login_required(login_url='http://foxnews.com')
def view_name(request):
(yes that's a joke)
I just discovered I should be using reverse_lazy, so this is the ultimate solution:
#login_required(login_url=reverse_lazy('bad!'))
def view_name(request):
Strange this would cause a ViewDoesNotExist error.
I had a similar error:
It was urls.py of the app.
I forgot to add '' in the starting of urlpatterns
SOLUTION:
just add '', to the urlpatterns
from django.conf.urls import patterns,include,url
urlpatterns = patterns('',
url(r'^profile<url name>/$','userprofile.views.user_profile<location of view>'),
)