Django+Haystack: Exception Value: 'module' object has no attribute 'get_model' - django-haystack

I set up a very simple project to try out Haystack using a Whoosh engine, mostly following the example in the documentation. I installed everything using pip and no version numbers, so I should have the latest release versions.
I'm getting this error and I have no idea what I'm supposed to do now, I cannot find anything similar though I've scoured Google. Please help!
The project folder structure is very simple, with one app called cat.
project
|-cat
| |-migrations
| |-admin.py, apps.py, models.py, search_indexes.py
|-templates
| |-search
| |-indexes
| | |-cat
| | |-cat_text.txt
| |-search.html
|-manage.py, settings.py, urls.py
The error I'm getting is:
Environment:
Request Method: GET
Request URL: http://localhost:8000/search/?q=felix&models=cat.cat
Django Version: 1.9.4
Python Version: 2.7.10
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'haystack',
'cat',]
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "/Users/lebouuski/projects/django/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/Users/lebouuski/projects/django/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/lebouuski/projects/django/lib/python2.7/site-packages/haystack/views.py" in __call__
51. self.results = self.get_results()
File "/Users/lebouuski/projects/django/lib/python2.7/site-packages/haystack/views.py" in get_results
91. return self.form.search()
File "/Users/lebouuski/projects/django/lib/python2.7/site-packages/haystack/forms.py" in search
116. return sqs.models(*self.get_models())
File "/Users/lebouuski/projects/django/lib/python2.7/site-packages/haystack/forms.py" in get_models
110. search_models.append(models.get_model(*model.split('.')))
Exception Type: AttributeError at /search/
Exception Value: 'module' object has no attribute 'get_model'
models.py:
class Cat(models.Model):
name = models.CharField(max_length=255)
birth_date = models.DateField(default=datetime.date.today)
bio = models.TextField(blank=True)
created = models.DateTimeField(default=datetime.datetime.now)
updated = models.DateTimeField(default=datetime.datetime.now)
def __unicode__(self):
return self.name
#models.permalink
def get_absolute_url(self):
return ('cat_detail', [], {'id': self.id})
search_indexes.py
class CatIndex(indexes.BasicSearchIndex, indexes.Indexable):
def get_model(self):
return Cat

For anyone else struggling with this, this is all due to a little change in Django 1.9, in which the get_model() method is moved to the django.apps.apps module, and is no longer available from django.db
The issue is resolved now in Haystack community, so updating to the newest version, from their GitHub repository (and not PyPI) must solve it.
The following should solve it:
pip install git+https://github.com/django-haystack/django-haystack.git
Or you can simply downgrade to Django 1.8 as Sam suggested.
You can find more over this issue here

Solution: downgrade Django from 1.9 to 1.8
sudo pip install Django==1.8
Motivations here: link

Related

Django Content Management System [duplicate]

My setup is Windows 10, Python 3.7, Apache 2.4/mod_wsgi. When I add this enctype="multipart/form-data" in my form (just by adding this attribute, only -- no files are attached to the form) I get this error when submitting:
Django Version: 1.8.5
Exception Type: RuntimeError
Exception Value: generator raised StopIteration
Exception Location: c:\users\holistic\envs\vitadmin\lib\site-packages\django\http\multipartparser.py in read, line 337
Python Executable: C:\Apache24\bin\httpd.exe
Python Version: 3.7.3
My Django code is this:
elif request.method == "POST":
rid = request.POST.get("recipe", "")
title = request.POST.get("title")
content = request.POST.get("content")
tag_names = request.POST.getlist("tags")
image = request.FILES.get("image")
if rid:
recipe = get_object_or_404(FoodRecipe, pk=rid)
else:
recipe = FoodRecipe.objects.create(title=title)
recipe.content = content
recipe.title = title
if image:
recipe.featured = image
for tn in tag_names:
tag, cr = Tag.objects.get_or_create(
name=tn
)
recipe.tags.add(tag)
recipe.save()
And this is full traceback:
Environment:
Request Method: POST
Request URL: http://192.168.1.250/recipes/add/
Django Version: 1.8.5
Python Version: 3.7.3
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'tinymce',
'sekizai',
'sorl.thumbnail',
'recipes',
'guides',
'inbox',
'appdata',
'account',
'customer',
'core')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
'account.middleware.PasswordChangeMiddleware.PasswordChangeMiddleware')
Traceback:
File "c:\users\holistic\envs\vitadmin\lib\site-packages\django\core\handlers\base.py" in get_response
125. response = middleware_method(request, callback, callback_args, callback_kwargs)
File "c:\users\holistic\envs\vitadmin\lib\site-packages\django\middleware\csrf.py" in process_view
174. request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
File "c:\users\holistic\envs\vitadmin\lib\site-packages\django\core\handlers\wsgi.py" in _get_post
137. self._load_post_and_files()
File "c:\users\holistic\envs\vitadmin\lib\site-packages\django\http\request.py" in _load_post_and_files
260. self._post, self._files = self.parse_file_upload(self.META, data)
File "c:\users\holistic\envs\vitadmin\lib\site-packages\django\http\request.py" in parse_file_upload
225. return parser.parse()
File "c:\users\holistic\envs\vitadmin\lib\site-packages\django\http\multipartparser.py" in parse
149. for item_type, meta_data, field_stream in Parser(stream, self._boundary):
File "c:\users\holistic\envs\vitadmin\lib\site-packages\django\http\multipartparser.py" in __iter__
628. yield parse_boundary_stream(sub_stream, 1024)
File "c:\users\holistic\envs\vitadmin\lib\site-packages\django\http\multipartparser.py" in parse_boundary_stream
567. chunk = stream.read(max_header_size)
File "c:\users\holistic\envs\vitadmin\lib\site-packages\django\http\multipartparser.py" in read
337. out = b''.join(parts())
Exception Type: RuntimeError at /recipes/add/
Exception Value: generator raised StopIteration
Any ideas what is going wrong?
PS: Same django application worked fine in Linux/Nginx/Gunicorn/Python2.7 setup. So, I guess it must some misconfiguration between Django/Python/Apache.
Your Django is very old and you need to update. This is a Python 3.7 compatibility problem that the Django devs already fixed four years ago, back when it was just a PendingDeprecationWarning on Python 3.5.
In fact, you are on the very last Django version that doesn't have the fix. Even 1.8.6 has the fix.

AWS Lambda Layers - module 'dicttoxml' has no attribute 'dicttoxml'

I have a AWS Lambda function based on python 3.7 and trying to use a module dicttoxml via AWS layers. My Python code is as below:
import json
import dicttoxml
def lambda_handler(event, context):
xml = dicttoxml.dicttoxml({"name": "Foo"})
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
At my local machine, it works perfectly fine but Lambda gives error as below:
{
"errorMessage": "module 'dicttoxml' has no attribute 'dicttoxml'",
"errorType": "AttributeError",
"stackTrace": [
" File \"/var/task/lambda_function.py\", line 4, in lambda_handler\n xml = dicttoxml.dicttoxml({\"name\": \"Ankur\"})\n"
]
}
The directory structure of dicttoxml layer is as below:
dicttoxml.zip > python > dicttoxml > dicttoxml.py
I feel puzzled, what is wrong here?
I created the custom layer with dicttoxml can confirm that it works.
The technique used includes docker tool described in the recent AWS blog:
How do I create a Lambda layer using a simulated Lambda environment with Docker?
Thus for this question, I verified it as follows:
Create empty folder, e.g. mylayer.
Go to the folder and create requirements.txt file with the content of
echo dicttoxml > ./requirements.txt
Run the following docker command:
docker run -v "$PWD":/var/task "lambci/lambda:build-python3.7" /bin/sh -c "pip install -r requirements.txt -t python/lib/python3.7/site-packages/; exit"
Create layer as zip:
zip -9 -r mylayer.zip python
Create lambda layer based on mylayer.zip in the AWS Console. Don't forget to specify Compatible runtimes to python3.7.
Test the layer in lambda using the following lambda function:
import dicttoxml
def lambda_handler(event, context):
print(dir(dicttoxml))
The function executes correctly:
['LOG', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', 'collections', 'convert', 'convert_bool', 'convert_dict', 'convert_kv', 'convert_list', 'convert_none', 'default_item_func', 'dicttoxml', 'escape_xml', 'get_unique_id', 'get_xml_type', 'ids', 'key_is_valid_xml', 'logging', 'long', 'make_attrstring', 'make_id', 'make_valid_xml_name', 'numbers', 'parseString', 'randint', 'set_debug', 'unicode', 'unicode_literals', 'unicode_me', 'version', 'wrap_cdata']

The run time error by import python module

I am trying to make correctly import the function "mmenu" from another module
I got a run time error:
Traceback (most recent call last):
File "path.../venv/src/routes.py", line 4, in <module>
from venv.src.main_menu import mmenu
ModuleNotFoundError: No module named 'venv.src'
after Java this Python is a bit of a mystery to me :)
I have 2 files in the same "src" directory
main_menu.py
def mmenu():
menu = [{"name": "HOME", "url": "home"},
{"name": "fooo", "url": "foo"},
{"name": "bar", "url": "bar"},
{"name": "CONTACT", "url": "contact"}]
return menu
routes.py
from flask import Flask, render_template, request, flash, session, redirect, abort
from jinja2 import Template
from flask.helpers import url_for
from venv.src.main_menu import mmenu
app = Flask(__name__)
menu = mmenu
#app.route("/")
#app.route("/index")
def index():
# return "index"
print("loaded" + url_for('index'))
return render_template('index.html', title="Index page", menu=menu)
# ...
if __name__ == "__main__":
app.run(debug=True)
import was generated by IDE like:
from venv.src.parts.main_menu import mmenu
Your IDE (which IDE?) is likely misconfigured if it generates imports like that.
The venv itself, nor any src directory within them, shouldn't be within import paths.
You never mention you have a parts/ package, but from the import I'll assume you do, and your structure is something like
venv/
src/ # source root
routes.py
parts/ # parts package
__init__.py # (empty) init for parts package
main_menu.py
With this structure, main_menu is importable as parts.main_menu from routes.py assuming you start the program with python routes.py.
If you have __init__.py files in venv/ and/or src/, get rid of them; you don't want those directories to be assumed to be Python packages.

Error on deploying Python app to AWS Lambda

I have built a Python-Tornado app and am trying to deploy it to AWS Lambda using zappa. But, I am getting an error Error: Warning! Status check on the deployed lambda failed. A GET request to '/' yielded a 502 response code.
My folder structure inside the root folder is :
├── amortization.py
├── config.py
├── dmi-amort-dev-1557138776.zip
├── main.py
├── requirements.txt
├── venv
│   ├── bin
│  
└── zappa_settings.json
zappa deploy dev gives me :
Calling deploy for stage dev..
Downloading and installing dependencies..
- pandas==0.24.2: Using locally cached manylinux wheel
- numpy==1.16.3: Using locally cached manylinux wheel
- sqlite==python3: Using precompiled lambda package
Packaging project as zip.
Uploading dmi-amort-dev-1557143681.zip (30.8MiB)..
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 32.3M/32.3M [00:19<00:00, 1.94MB/s]
Scheduling..
Scheduled dmi-amort-dev-zappa-keep-warm-handler.keep_warm_callback with expression rate(4 minutes)!
Uploading dmi-amort-dev-template-1557143718.json (1.5KiB)..
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1.56K/1.56K [00:00<00:00, 10.6KB/s]
Waiting for stack dmi-amort-dev to create (this can take a bit)..
75%|█████████████████████████████████████████████████████████████████████████████████████████████████████▎ | 3/4 [00:09<00:04, 5.00s/res]
Deploying API Gateway..
Error: Warning! Status check on the deployed lambda failed. A GET request to '/' yielded a 502 response code.
zappa tail gives me
Traceback (most recent call last):
File "/var/task/handler.py", line 602, in lambda_handler
return LambdaHandler.lambda_handler(event, context)
File "/var/task/handler.py", line 245, in lambda_handler
handler = cls()
File "/var/task/handler.py", line 142, in __init__
wsgi_app_function = getattr(self.app_module, self.settings.APP_FUNCTION)
AttributeError: module 'main' has no attribute 'app'
zappa_settings.json:
{
"dev": {
"app_function": "main.app",
"aws_region": "ap-south-1",
"profile_name": "default",
"project_name": "dmi-amort",
"runtime": "python3.6",
"s3_bucket": "zappa-mekp457ye",
"manage_roles": false,
"role_name": "lambda-role",
}
}
main.py:
import tornado.web
from tornado.ioloop import IOLoop
from tornado.web import MissingArgumentError
from config import get_arguments
from amortization import get_amort_schedule
class MainHandler(tornado.web.RequestHandler):
def prepare(self):
"""Checking if all the required parameters are present."""
if self.request.method != 'POST':
self.write_error(status_code=405, message="Method not allowed")
return
self.parameters = dict()
for key in get_arguments():
try:
self.parameters[key] = self.get_argument(key)
except MissingArgumentError:
self.write_error(status_code=400,
message="Missing Argument(s)")
return
# checking if 'label' is provided
if 'label' in self.request.arguments.keys():
self.parameters['label'] = self.get_argument('label')
# Set up response dictionary.
self.response = dict()
def get(self, *args, **kwargs):
self.write_error(status_code=405, message="Method not allowed")
def post(self, *args, **kwargs):
"""Executes the main logic part."""
self.response = get_amort_schedule(self.parameters)
self.write_json()
def set_default_headers(self):
"""Sets content-type as 'application/json' for response as JSON."""
self.set_header('Content-Type', 'application/json')
def write_error(self, status_code, **kwargs):
"""Invokes when error occurs in processing the request."""
if 'message' not in kwargs:
if status_code == 405:
kwargs['message'] = 'Invalid HTTP method.'
else:
kwargs['message'] = 'Unknown error.'
kwargs["error"] = True
self.set_status(status_code=status_code)
self.response = dict(kwargs)
self.write_json()
def write_json(self):
"""Responsible for writing the response."""
if "status" in self.response:
self.set_status(self.response.get("status"))
self.set_default_headers()
self.write(self.response)
self.finish()
def main():
app = tornado.web.Application([
(r'/', MainHandler),
], debug=True)
# server = HTTPServer(app)
# server.bind(8888)
# server.start(0)
app.listen()
# app.run(host='0.0.0.0')
IOLoop.current().start()
if __name__ == '__main__':
main()
What is the mistake here and how can I fix it?
It looks like the deployment is succeeding, but when Zappa checks to see if the code is working, the return code is 502, which suggests that the lambda function is failing to run in the lambda environment.
Taking a look at the logs, the critical line is:
AttributeError: module 'main' has no attribute 'app'
And this is true, if we look at your code, at no point do you expose an attribute called app in main.py.
I'm not experienced with Tornado, but I suspect that if you move the declaration of app out of the main() function and into the root scope, then the handler should succeed.
For example:
# rest of the file...
self.finish()
app = tornado.web.Application([
(r'/', MainHandler),
], debug=True)
app.listen()
def main():
IOLoop.current().start()
if __name__ == '__main__':
main()

Django2.0 SMTPRecipientsRefused (550, b'Invalid authentication (you can only send from #yourdomain.xy or its aliases)')

I have a problem when I try to reset my password. I configured the settings.py according to Coreys tutorial on youtube:
Python Django - Email & Password or
Vitor Freitas instructions. Running that on my local virtual machine does not cause any problems.
Also when I run send_mail(mail_subject, message, mail_sender,[mail_recipient])
from from django.core.mail import send_mail does not cause any problems on my server in Canada - he (its a he :-)) can sent the email over the email service located in Austria.
The error message in the console or the browser is (see bottom for complete error message)
Request Method: POST
Request URL: http://mydomain.xy/password-reset/
Django Version: 2.0
Exception Type: SMTPRecipientsRefused
Exception Value: {'myemail#mydomain.xy': (550, b'Invalid authentication (you can only send from #mydomain.xy or its aliases)')}
Exception Location /usr/lib/python3.5/smtplib.py in sendmail, line 876
Python Executable: ~/django_env/bin/python3
Python Version: 3.5.2
Python Path:
['~/django_env/mwrench_dev',
'~/django_env/lib/python35.zip',
'~/django_env/lib/python3.5',
'~/django_env/lib/python3.5/plat-x86_64-linux-gnu',
'~/django_env/lib/python3.5/lib-dynload',
'/usr/lib/python3.5',
'/usr/lib/python3.5/plat-x86_64-linux-gnu',
'~/django_env/lib/python3.5/site-packages']
Something should be different between the send_mail() function from django.core.mail and the smtplib.py used from the backend. But I cannot find out what the problem is.
In my urls.py
path(r'password-reset/', auth_views.PasswordResetView.as_view(template_name='registration/password_reset_form.html'), ame='password_reset'),
path(r'password-reset-done/', auth_views.PasswordResetDoneView.as_view(template_name='registration/password_reset_done.html'), name='password_reset_done'),
path(r'password-reset-confirm/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name='registration/password_reset_confirm.html'), name='password_reset_confirm'),
Within the settings.py if defined those lines
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'mail.domainname.xy'
EMAIL_PORT = 587
EMAIL_USE_TLS=TRUE
EMAIL_HOST_USER='user#domainname.xy'
EMAIL_HOST_PASSWORD='mypassword'
**Complete error message:
Request Method: POST
Request URL: http://www.example.com/password-reset/
Django Version: 2.0
Python Version: 3.5.2
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'crispy_forms',
]
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "~/django_env/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
35. response = get_response(request)
File "~/django_env/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
128. response = self.process_exception_by_middleware(e, request)
File "~/django_env/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
126. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "~/django_env/lib/python3.5/site-packages/django/views/generic/base.py" in view
69. return self.dispatch(request, *args, **kwargs)
File "~/django_env/lib/python3.5/site-packages/django/utils/decorators.py" in _wrapper
62. return bound_func(*args, **kwargs)
File "~/django_env/lib/python3.5/site-packages/django/utils/decorators.py" in _wrapped_view
142. response = view_func(request, *args, **kwargs)
File "~/django_env/lib/python3.5/site-packages/django/utils/decorators.py" in bound_func
58. return func.__get__(self, type(self))(*args2, **kwargs2)
File "~/django_env/lib/python3.5/site-packages/django/contrib/auth/views.py" in dispatch
406. return super().dispatch(*args, **kwargs)
File "~/django_env/lib/python3.5/site-packages/django/views/generic/base.py" in dispatch
89. return handler(request, *args, **kwargs)
File "~/django_env/lib/python3.5/site-packages/django/views/generic/edit.py" in post
142. return self.form_valid(form)
File "~/django_env/lib/python3.5/site-packages/django/contrib/auth/views.py" in form_valid
419. form.save(**opts)
File "~/django_env/lib/python3.5/site-packages/django/contrib/auth/forms.py" in save
306. email, html_email_template_name=html_email_template_name,
File "~/django_env/lib/python3.5/site-packages/django/contrib/auth/forms.py" in send_mail
260. email_message.send()
File "~/django_env/lib/python3.5/site-packages/django/core/mail/message.py" in send
294. return self.get_connection(fail_silently).send_messages([self])
File "~/django_env/lib/python3.5/site-packages/django/core/mail/backends/smtp.py" in send_messages
110. sent = self._send(message)
File "~/django_env/lib/python3.5/site-packages/django/core/mail/backends/smtp.py" in _send
126. self.connection.sendmail(from_email, recipients, message.as_bytes(linesep='\r\n'))
File "/usr/lib/python3.5/smtplib.py" in sendmail
876. raise SMTPRecipientsRefused(senderrs)
Exception Type: SMTPRecipientsRefused at /password-reset/
Exception Value: {'emyemail#gmail.com': (550, b'Invalid authentication (you can only send from #mydomain.com or its aliases)')}
Found it Here
I needed to add the default sender variable to the settings.py file - I didn't know which one my Django-Setup was using.
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'mail.domainname.xy'
EMAIL_PORT = 587
EMAIL_USE_TLS=TRUE
EMAIL_HOST_USER='user#domainname.xy'
EMAIL_HOST_PASSWORD='mypassword'
Added:
DEFAULT_FROM_EMAIL = 'user#domainname.xy'
Thank you for watching the Post!

Resources