Related
I'm testing example code validate image field (Django custom validation in model form for imagefield (max file size etc.)):
models.py
from django.db import models
from filer.fields.image import FilerImageField
class Event(models.Model):
# (...)
banner = FilerImageField(verbose_name='Banner')
admin.py
from django.contrib import admin
from django import forms
from PIL import Image
from .models import Event
class EventForm(forms.ModelForm):
class Meta:
model = Event
fields = '__all__'
def clean_banner(self):
image = self.cleaned_data.get('banner', False)
if image:
img = Image.open(image)
img.load()
width, height = img.size
max_width = 879
max_height = 392
if width > max_width or width < max_width or height > max_height or height < max_height:
raise forms.ValidationError('Imagem está com dimensão incorreta: %s x %s pixels. Insira uma imagem com %s x %s pixels.'
%(width, height, max_width, max_height))
# Máx 3MB
if len(image) > (3 * 1024 * 1024):
raise forms.ValidationError('Arquivo de imagem muito grande (máximo 3MB).')
name_type, ext = image.content_type.split('/')
if not (name_type == 'image' and ext.lower() in ['png', 'jpg', 'jpeg']):
raise forms.ValidationError('Por favor, use imagem em formato JPG, JPEG ou PNG.')
else:
raise forms.ValidationError('Não foi possível ler a imagem carregada.')
return image
error when registering image not django-admin. Version: Pillow==4.3.0, Python==3.6
Traceback (most recent call last):
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\PIL\Image.py", line 2534, in open
fp.seek(0)
AttributeError: 'Image' object has no attribute 'seek'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
response = get_response(request)
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\contrib\admin\options.py", line 551, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\utils\decorators.py", line 149, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\views\decorators\cache.py", line 57, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\contrib\admin\sites.py", line 224, in inner
return view(request, *args, **kwargs)
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\contrib\admin\options.py", line 1508, in add_view
return self.changeform_view(request, None, form_url, extra_context)
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\utils\decorators.py", line 67, in _wrapper
return bound_func(*args, **kwargs)
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\utils\decorators.py", line 149, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\utils\decorators.py", line 63, in bound_func
return func.__get__(self, type(self))(*args2, **kwargs2)
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\contrib\admin\options.py", line 1408, in changeform_view
return self._changeform_view(request, object_id, form_url, extra_context)
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\contrib\admin\options.py", line 1440, in _changeform_view
if form.is_valid():
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\forms\forms.py", line 183, in is_valid
return self.is_bound and not self.errors
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\forms\forms.py", line 175, in errors
self.full_clean()
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\forms\forms.py", line 384, in full_clean
self._clean_fields()
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\django\forms\forms.py", line 405, in _clean_fields
value = getattr(self, 'clean_%s' % name)()
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\integrafundaj\events\admin.py", line 19, in clean_banner
img = Image.open(image)
File "C:\Users\Lidy Monteiro\Developer\integra-fundaj\.myvenv\lib\site-packages\PIL\Image.py", line 2536, in open
fp = io.BytesIO(fp.read())
AttributeError: 'Image' object has no attribute 'read'
I tried img = Image.open(image, mode='r') in function clean_banne, but it does not work. how to solve? the problem is in the python version?
According to Pillow documentation Python 3.6 is not yet supported. Please try another version of python.
The error happens when trying to take a quiz. Although the attribute error of my page is the same as in this topic, the solution has not solved my problem.
I've tried the solution mentioned in the topic above but it hasn't solved my problem. I've mixed all the apps in that Django Quiz in one, having the models in the same file and so on. For the moment it has worked properly, and I've been able to manage the settings in the 'admin' page without any problem.
The issue relies on when taking the quiz, I recieve this traceback:
Internal Server Error: /myquiz/take/
Traceback (most recent call last):
File "C:\P4\myapp\models.py", line 359, in user_sitting
sitting = self.get(user=user, quiz=quiz, complete=False)
File "C:\Python\lib\site-packages\django-1.9.1-py3.5.egg\django\db\models\manager.py", line 122, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Python\lib\site-packages\django-1.9.1-py3.5.egg\django\db\models\query.py", line 387, in get
self.model._meta.object_name
myapp.models.DoesNotExist: Sitting matching query does not exist.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Python\lib\site-packages\django-1.9.1-py3.5.egg\django\core\handlers\base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Python\lib\site-packages\django-1.9.1-py3.5.egg\django\core\handlers\base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Python\lib\site-packages\django-1.9.1-py3.5.egg\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "C:\P4\myapp\views.py", line 163, in dispatch
self.quiz)
File "C:\P4\myapp\models.py", line 361, in user_sitting
sitting = self.new_sitting(user, quiz)
File "C:\P4\myapp\models.py", line 339, in new_sitting
questions = ",".join(map(str, questions_set)) + ","
File "C:\Python\lib\site-packages\django-1.9.1-py3.5.egg\django\db\models\query.py", line 258, in __iter__
self._fetch_all()
File "C:\Python\lib\site-packages\django-1.9.1-py3.5.egg\django\db\models\query.py", line 1074, in _fetch_all
self._result_cache = list(self.iterator())
File "C:\Python\lib\site-packages\model_utils\managers.py", line 80, in iterator
sub_obj = self._get_sub_obj_recurse(obj, s)
File "C:\Python\lib\site-packages\model_utils\managers.py", line 153, in _get_sub_obj_recurse
node = getattr(obj, rel)
AttributeError: 'int' object has no attribute 'essay_question'
It seems like the problem might be in essay_question model or in Sitting model. However, I can't find an answer to this problem. Here there are the pieces of code I think that are related with the error, but if more are needed just ask (most of the parts remain the same of the Quiz app of Django).
Sitting manager model:
class SittingManager(models.Manager):
def new_sitting(self, user, quiz):
if quiz.random_order is True:
questions_set = quiz.questions_set.all() \
.select_subclasses() \
.order_by('?')
else:
questions_set = quiz.questions_set.all() \
.select_subclasses()
questions_set = questions_set.values_list('id', flat=True)
if questions_set.count() == 0:
raise ImproperlyConfigured('Question set of the quiz is empty. '
'Please configure questions properly')
if quiz.max_questions and quiz.max_questions < questions_set.count():
questions_set = questions_set[:quiz.max_questions]
questions = ",".join(map(str, questions_set)) + ","
new_sitting = self.create(user=user,
quiz=quiz,
question_order=questions,
question_list=questions,
incorrect_questions="",
current_score=0,
complete=False,
user_answers='{}')
return new_sitting
def user_sitting(self, user, quiz):
if quiz.single_attempt is True and self.filter(user=user,
quiz=quiz,
complete=True)\
.exists():
return False
try:
sitting = self.get(user=user, quiz=quiz, complete=False)
except Sitting.DoesNotExist:
sitting = self.new_sitting(user, quiz)
except Sitting.MultipleObjectsReturned:
sitting = self.filter(user=user, quiz=quiz, complete=False)[0]
return sitting
And the QuizTake view:
EDITED
I would appreciate an answer since it's not the same solution of the other similar error with this app. I would provide more needed info and thank you for the help.
.
EDIT 2:
I'm getting this now while trying to get to 'myquiz/take' view:
Internal Server Error: /myquiz/take/
Traceback (most recent call last):
File "C:\Python\lib\site-packages\django-1.9.1-py3.5.egg\django\core\handlers\base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Python\lib\site-packages\django-1.9.1-py3.5.egg\django\core\handlers\base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Python\lib\site-packages\django-1.9.1-py3.5.egg\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "C:\P4\myapp\views.py", line 171, in dispatch
return super(QuizTake, self).dispatch(request, *args, **kwargs)
File "C:\Python\lib\site-packages\django-1.9.1-py3.5.egg\django\views\generic\base.py", line 88, in dispatch
return handler(request, *args, **kwargs)
File "C:\Python\lib\site-packages\django-1.9.1-py3.5.egg\django\views\generic\edit.py", line 213, in get
return self.render_to_response(self.get_context_data())
File "C:\P4\myapp\views.py", line 206, in get_context_data
context = super(QuizTake, self).get_context_data(**kwargs)
File "C:\Python\lib\site-packages\django-1.9.1-py3.5.egg\django\views\generic\edit.py", line 122, in get_context_data
kwargs['form'] = self.get_form()
File "C:\Python\lib\site-packages\django-1.9.1-py3.5.egg\django\views\generic\edit.py", line 35, in get_form_with_form_class
return get_form(self, form_class=form_class)
File "C:\P4\myapp\views.py", line 184, in get_form
return form_class(**self.get_form_kwargs())
TypeError: __init__() missing 1 required positional argument: 'question'
Here are extracts of my views.py (which seem to be causing the error):
def dispatch(self, request, *args, **kwargs):
self.quiz = get_object_or_404(Quiz, url=self.kwargs['quiz_name'])
if self.quiz.draft and not request.user.has_perm('quiz.change_quiz'):
raise PermissionDenied
self.logged_in_user = self.request.user.is_authenticated()
if self.logged_in_user:
self.sitting = Sitting.objects.user_sitting(request.user,
self.quiz)
else:
self.sitting = self.anon_load_sitting()
if self.sitting is False:
return render(request, 'single_complete.html')
return super(QuizTake, self).dispatch(request, *args, **kwargs)
Get_form:
def get_form(self, form_class):
if self.logged_in_user:
self.questions = self.sitting.get_first_questions()
self.progress = self.sitting.progress()
else:
self.questions = self.anon_next_questions()
self.progress = self.anon_sitting_progress()
if self.questions.__class__ is Essay_Questions:
form_class = EssayForm
return form_class(**self.get_form_kwargs())
def get_form_kwargs(self):
kwargs = super(QuizTake, self).get_form_kwargs()
return dict(kwargs, questions=self.questions)
FORM_VALID and get_context_data
def form_valid(self, form):
if self.logged_in_user:
self.form_valid_user(form)
if self.sitting.get_first_questions() is False:
return self.final_result_user()
else:
self.form_valid_anon(form)
if not self.request.session[self.quiz.anon_q_list()]:
return self.final_result_anon()
self.request.POST = {}
return super(QuizTake, self).get(self, self.request)
def get_context_data(self, **kwargs):
context = super(QuizTake, self).get_context_data(**kwargs)
context['question'] = self.questions
context['quiz'] = self.quiz
if hasattr(self, 'previous'):
context['previous'] = self.previous
if hasattr(self, 'progress'):
context['progress'] = self.progress
return context
myapp.models.DoesNotExist: Sitting matching query does not exist.
This means exactly what it says. YOu are trying to fetch a Sitting object that does not exist. So you need to sorround line 359 with try except to handle that situation cleanly. In fact you can simplify that whole method as follows.
def user_sitting(self, user, quiz):
if quiz.single_attempt is True and self.filter(user=user,
quiz=quiz,
complete=True)\
.exists():
return False
try:
return self.filter(user=user,quiz=quiz,complete=True)[0]
except IndexError:
return sitting = self.new_sitting(user, quiz)
Simpler code is easier to maintain and you are cutting down the number of queries, which leads to a performance improvement.
AttributeError: 'int' object has no attribute 'essay_question'
What this means is that you think you h have a Questions instance but what you actually have is a meta. The rest of the stacktrace gives you the lines of execution that lead to this error. Look at the lines that mention your own code, some where near they you are calling a method that should return a Questions instance but returns int instead.
The reason that it used to work and doesn't work anymore is what's known as a regression error. Changes to some section of code has made another section misbehave. The most popular, sustainable way to tackle them is with unit testing.
I have custom pipeline in my django project. Following this example I'm trying to get access token (to get data from google plus) but it returns me TypeError: string indices must be integers.
Custom pipeline:
def user_details(strategy, details, response, user=None, *args, **kwargs):
....
if user:
if kwargs['is_new']:
if "google" in kwargs['backend'].redirect_uri:
...
try:
social = user.social_auth.get(provider='google-plus')
access_token = logger.warning(social.extra_data['access_token'])
....
except HTTPError:
pass
.....
Full traceback:
Traceback (most recent call last):
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/django/views/decorators/cache.py", line 57, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/social/apps/django_app/utils.py", line 51, in wrapper
return func(request, backend, *args, **kwargs)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/social/apps/django_app/views.py", line 28, in complete
redirect_name=REDIRECT_FIELD_NAME, *args, **kwargs)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/social/actions.py", line 43, in do_complete
user = backend.complete(user=user, *args, **kwargs)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/social/backends/base.py", line 41, in complete
return self.auth_complete(*args, **kwargs)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/social/utils.py", line 229, in wrapper
return func(*args, **kwargs)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/social/backends/google.py", line 158, in auth_complete
*args, **kwargs)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/social/utils.py", line 229, in wrapper
return func(*args, **kwargs)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/social/backends/oauth.py", line 398, in do_auth
return self.strategy.authenticate(*args, **kwargs)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/social/strategies/django_strategy.py", line 96, in authenticate
return authenticate(*args, **kwargs)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/django/contrib/auth/__init__.py", line 74, in authenticate
user = backend.authenticate(**credentials)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/social/backends/base.py", line 82, in authenticate
return self.pipeline(pipeline, *args, **kwargs)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/social/backends/base.py", line 85, in pipeline
out = self.run_pipeline(pipeline, pipeline_index, *args, **kwargs)
File "/home/linevich/.virtualenvs/tathros/lib/python3.4/site-packages/social/backends/base.py", line 112, in run_pipeline
result = func(*args, **out) or {}
File "/home/linevich/projects/tathros/proto/pipeline.py", line 54, in user_details
auth_token = social.extra_data['access_token']
TypeError: string indices must be integers
The solutuion was simple:
auth_token = json.loads(social.extra_data)['access_token']
This seems to be a significant simple problem, but somehow I cant find a solution.
As I press the save button the write method will be executed. I want to change a value (or call a function) of the current model every time the write method is called, so I have overridden the write() method of my model as
#api.multi
def write(self, vals):
self.flaeche = 37
return super(lager, self).write(vals)
(the model is lager.py and the field is flaeche = fields.Float(string=u"Fläche (m²)"))
The Error: RuntimeError: maximum recursion depth exceeded
Traceback (most recent call last):
File "/home/tertia/workspace/odoo8/openerp/http.py", line 530, in _handle_exception
return super(JsonRequest, self)._handle_exception(exception)
File "/home/tertia/workspace/odoo8/openerp/http.py", line 567, in dispatch
result = self._call_function(**self.params)
File "/home/tertia/workspace/odoo8/openerp/http.py", line 303, in _call_function
return checked_call(self.db, *args, **kwargs)
File "/home/tertia/workspace/odoo8/openerp/service/model.py", line 113, in wrapper
return f(dbname, *args, **kwargs)
File "/home/tertia/workspace/odoo8/openerp/http.py", line 300, in checked_call
return self.endpoint(*a, **kw)
File "/home/tertia/workspace/odoo8/openerp/http.py", line 796, in __call__
return self.method(*args, **kw)
File "/home/tertia/workspace/odoo8/openerp/http.py", line 396, in response_wrap
response = f(*args, **kw)
File "/home/tertia/workspace/odoo8/openerp/addons/web/controllers/main.py", line 936, in call_kw
return self._call_kw(model, method, args, kwargs)
File "/home/tertia/workspace/odoo8/openerp/addons/web/controllers/main.py", line 928, in _call_kw
return getattr(request.registry.get(model), method)(request.cr, request.uid, *args, **kwargs)
File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/tertia/workspace/odoo8/openerp/api.py", line 363, in old_api
result = method(recs, *args, **kwargs)
File "/home/tertia/workspace/odoo8/custom_modules/g4e_config/lager.py", line 225, in write
self.flaeche = 37
File "/home/tertia/workspace/odoo8/openerp/fields.py", line 853, in __set__
record.write({self.name: self.convert_to_write(value)})
File "/home/tertia/workspace/odoo8/openerp/api.py", line 239, in wrapper
return new_api(self, *args, **kwargs)
File "/home/tertia/workspace/odoo8/custom_modules/g4e_config/lager.py", line 225, in write
self.flaeche = 37
File "/home/tertia/workspace/odoo8/openerp/fields.py", line 853, in __set__
record.write({self.name: self.convert_to_write(value)})
File "/home/tertia/workspace/odoo8/openerp/api.py", line 239, in wrapper
return new_api(self, *args, **kwargs)
.....
File "/home/tertia/workspace/odoo8/custom_modules/g4e_config/lager.py", line 225, in write
self.flaeche = 37
File "/home/tertia/workspace/odoo8/openerp/fields.py", line 853, in __set__
record.write({self.name: self.convert_to_write(value)})
File "/home/tertia/workspace/odoo8/openerp/api.py", line 239, in wrapper
return new_api(self, *args, **kwargs)
File "/home/tertia/workspace/odoo8/custom_modules/g4e_config/lager.py", line 225, in write
self.flaeche = 37
File "/home/tertia/workspace/odoo8/openerp/fields.py", line 853, in __set__
record.write({self.name: self.convert_to_write(value)})
File "/home/tertia/workspace/odoo8/openerp/api.py", line 239, in wrapper
return new_api(self, *args, **kwargs)
File "/home/tertia/workspace/odoo8/custom_modules/g4e_config/lager.py", line 224, in write
super(lager, self).write(vals)
File "/home/tertia/workspace/odoo8/openerp/api.py", line 239, in wrapper
return new_api(self, *args, **kwargs)
File "/home/tertia/workspace/odoo8/openerp/api.py", line 546, in new_api
result = method(self._model, cr, uid, self.ids, *args, **kwargs)
File "/home/tertia/workspace/odoo8/openerp/addons/mail/mail_thread.py", line 435, in write
self.message_auto_subscribe(cr, uid, ids, values.keys(), context=context, values=values)
File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/tertia/workspace/odoo8/openerp/addons/mail/mail_thread.py", line 1883, in message_auto_subscribe
header_subtype_ids = subtype_obj.search(cr, uid, ['|', ('res_model', '=', False), ('parent_id.res_model', '=', self._name)], context=context)
File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/tertia/workspace/odoo8/openerp/models.py", line 1639, in search
return self._search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count)
File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/tertia/workspace/odoo8/openerp/models.py", line 4621, in _search
query = self._where_calc(cr, user, args, context=context)
File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/tertia/workspace/odoo8/openerp/models.py", line 4444, in _where_calc
e = expression.expression(cr, user, domain, self, context)
File "/home/tertia/workspace/odoo8/openerp/osv/expression.py", line 646, in __init__
self.parse(cr, uid, context=context)
File "/home/tertia/workspace/odoo8/openerp/osv/expression.py", line 847, in parse
right_ids = comodel.search(cr, uid, [(path[1], operator, right)], context=context)
File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/tertia/workspace/odoo8/openerp/models.py", line 1639, in search
return self._search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count)
File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/tertia/workspace/odoo8/openerp/models.py", line 4615, in _search
self.check_access_rights(cr, access_rights_uid or user, 'read')
File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/tertia/workspace/odoo8/openerp/models.py", line 3477, in check_access_rights
return self.pool.get('ir.model.access').check(cr, uid, self._name, operation, raise_exception)
File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "<string>", line 2, in check
File "/home/tertia/workspace/odoo8/openerp/tools/cache.py", line 117, in lookup
r = d[key]
File "/home/tertia/workspace/odoo8/openerp/tools/func.py", line 66, in wrapper
return func(self, *args, **kwargs)
File "/home/tertia/workspace/odoo8/openerp/tools/lru.py", line 38, in __getitem__
self[a[0]] = a[1]
File "/home/tertia/workspace/odoo8/openerp/tools/func.py", line 66, in wrapper
return func(self, *args, **kwargs)
File "/home/tertia/workspace/odoo8/openerp/tools/lru.py", line 44, in __setitem__
del self[obj]
The same happens when I want to call a function of the lager model.
What am I doing wrong?
The problem is that by writing self.flaeche = 37 you are changing the record, which means implicitly calling the write() method on the model. When you call write() from write() you obviously end up with recursion.
You can do something similar to this instead:
#api.multi
def write(self, vals):
vals['flaeche'] = 37
return super(lager, self).write(vals)
This way there are no additional writes - you just change the values for a write that was about to happen anyway.
If you want to allow people to explicitly overwrite the value of 37 you can do this:
#api.multi
def write(self, vals):
if 'flaeche' not in vals:
vals['flaeche'] = 37
return super(lager, self).write(vals)
In your lager.write method, the self.flaeche=37 statement triggers a call to field.__set__() which calls record.write() - record being here the current lager instance, hence your infinite recursion.
I don't know zilch about odoo, but hopefully there must be a way to set a field without triggering a call to write - else, well, bad luck.
This way works for me, calling the ancestor class:
#api.multi
def write(self, vals):
vals['flaeche'] = 37
return super(models.Model, self).write(vals)
The solution is appropiate when you are overwriting a new model, not an inherited one.
I'm using django-rq, the django bindings for python-rq, to try generate a PDF asynchronously. The class TemplateProcesser initializes with two arguments and automatically generates the PDF in the __init__ function. This works fine synchronously, outside of django-rq, but with django-rq it fails with this error:
Error:
AttributeError: type object 'TemplateProcesser' has no attribute 'rsplit'
From this call:
django_rq.enqueue(TemplateProcesser, nail_order=serializer.object, user_photo=base64_image)
Any idea on how to correctly include the uninstantiated class in django-rq?
Class:
class TemplateProcesser(object):
def __init__(self, nail_order, user_photo, *args, **kwargs):
self.nail_order = nail_order
self.user_photo = user_photo
...
self.procces_template()
...
StackTrace:
Traceback (most recent call last):
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/rq/worker.py", line 426, in perform_job
rv = job.perform()
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/rq/job.py", line 386, in perform
self._result = self.func(*self.args, **self.kwargs)
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/rq/job.py", line 154, in func
return import_attribute(self.func_name)
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/rq/utils.py", line 168, in import_attribute
module_name, attribute = name.rsplit('.', 1)
AttributeError: type object 'TemplateProcesser' has no attribute 'rsplit'
Traceback after metaperture's answer:
Traceback (most recent call last):
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/django/core/handlers/base.py", line 114, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/django/views/generic/base.py", line 69, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 57, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/rest_framework/views.py", line 400, in dispatch
response = self.handle_exception(exc)
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/rest_framework/views.py", line 397, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/admin/dev/ncla-web/ncla/api/views.py", line 91, in post
django_rq.enqueue(self.template_processor_factory, **parameter_dict)
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/django_rq/queues.py", line 162, in enqueue
return get_queue().enqueue(func, *args, **kwargs)
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/rq/queue.py", line 213, in enqueue
description=description, depends_on=depends_on)
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/django_rq/queues.py", line 42, in enqueue_call
return self.original_enqueue_call(*args, **kwargs)
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/django_rq/queues.py", line 37, in original_enqueue_call
return super(DjangoRQ, self).enqueue_call(*args, **kwargs)
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/rq/queue.py", line 176, in enqueue_call
return self.enqueue_job(job)
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/rq/queue.py", line 232, in enqueue_job
job.save()
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/rq/job.py", line 360, in save
connection.hmset(key, self.dump())
File "/Users/admin/dev/ncla-web/env/lib/python2.7/site-packages/rq/job.py", line 329, in dump
obj['data'] = dumps(self.job_tuple)
File "/Users/admin/dev/ncla-web/env/bin/../lib/python2.7/copy_reg.py", line 70, in _reduce_ex
raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle BytesIO objects
Looks like python-rq expects a function as the first argument. I would try:
def template_processor_factory(*args, **kwargs):
return TemplateProcessor(*args, **kwargs)
django_rq.enqueue(template_processer_factory, nail_order=serializer.object,
user_photo=base64_image)