Django RQ handles long serializer job - python

I have validator in the model. It does validation and then validated data will be saved to database.
Problem:
Validation and commit to database takes very long time.
Therefore I decided to use Django-rq to handle the time consuming task
views.py
def save_serializer(serializer, request):
serializer.save()
if bool(serializer.errors):
# If it has no errors it will be empty dictionary and bool({}) is False
msg = serializer.errors
else:
msg = serializer.data
email = EmailMessage(
'Message From jobs.siamsbrand.com',
msg,
settings.C0D1UM_SENDER,
[request.user.email]
)
email.send()
class PriceListExcelFileList(generics.ListCreateAPIView):
permission_classes = (DRYPermissions,)
queryset = PriceListExcelFile.objects.all()
serializer_class = PriceListExcelFileSerializer
def perform_create(self, serializer, request):
"""
:param serializer:
:return:
"""
django_rq.enqueue(save_serializer, serializer, request)
def create(self, request, *args, **kwargs):
"""
I need to override the default behaviour because I am going to use rq and let it be an email notification
:param request:
:param args:
:param kwargs:
:return:
"""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer, request)
headers = self.get_success_headers(serializer.data)
data = {
"id": "Processing",
"file": "The response will be email to " + str(request.user.email) + " shortly",
"permission": "-"
}
return Response(data, status=status.HTTP_201_CREATED, headers=headers)
Error Messages:
File "/Users/el/Code/siam-sbrand/portal/apps/price_list_excel_files/views.py", line 52, in create
self.perform_create(serializer, request)
File "/Users/el/Code/siam-sbrand/portal/apps/price_list_excel_files/views.py", line 40, in perform_create
django_rq.enqueue(save_serializer, serializer, request)
File "/Users/el/.pyenv/versions/siam-sbrand/lib/python3.6/site-packages/django_rq/queues.py", line 208, in enqueue
return get_queue().enqueue(func, *args, **kwargs)
File "/Users/el/.pyenv/versions/siam-sbrand/lib/python3.6/site-packages/rq/queue.py", line 274, in enqueue
job_id=job_id, at_front=at_front, meta=meta)
File "/Users/el/.pyenv/versions/siam-sbrand/lib/python3.6/site-packages/django_rq/queues.py", line 60, in enqueue_call
return self.original_enqueue_call(*args, **kwargs)
File "/Users/el/.pyenv/versions/siam-sbrand/lib/python3.6/site-packages/django_rq/queues.py", line 56, in original_enqueue_call
return super(DjangoRQ, self).enqueue_call(*args, **kwargs)
File "/Users/el/.pyenv/versions/siam-sbrand/lib/python3.6/site-packages/rq/queue.py", line 227, in enqueue_call
job = self.enqueue_job(job, at_front=at_front)
File "/Users/el/.pyenv/versions/siam-sbrand/lib/python3.6/site-packages/rq/queue.py", line 292, in enqueue_job
job.save(pipeline=pipe)
File "/Users/el/.pyenv/versions/siam-sbrand/lib/python3.6/site-packages/rq/job.py", line 465, in save
connection.hmset(key, self.to_dict())
File "/Users/el/.pyenv/versions/siam-sbrand/lib/python3.6/site-packages/rq/job.py", line 429, in to_dict
obj['data'] = self.data
File "/Users/el/.pyenv/versions/siam-sbrand/lib/python3.6/site-packages/rq/job.py", line 227, in data
self._data = dumps(job_tuple)
TypeError: cannot serialize '_io.BufferedReader' object
"POST /api/price-list-excel-files/ HTTP/1.1" 500 20430

It can handle plain function not an instance. Then I have to use thread to do long time consuming task

Related

facing problem to push data to backend from local storage in react

I tried alot to fix that but I need little help to figure out what I'm doing wrong.
When I make post request POST /api/appointment/make/ Request gets failed with status code 500
Internal Server Error: /api/appointment/make/
Traceback (most recent call last):
File "E:\eCommerce_Projects\remote-hospital-v3\venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "E:\eCommerce_Projects\remote-hospital-v3\venv\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "E:\eCommerce_Projects\remote-hospital-v3\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "E:\eCommerce_Projects\remote-hospital-v3\venv\lib\site-packages\django\views\generic\base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "E:\eCommerce_Projects\remote-hospital-v3\venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "E:\eCommerce_Projects\remote-hospital-v3\venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "E:\eCommerce_Projects\remote-hospital-v3\venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "E:\eCommerce_Projects\remote-hospital-v3\venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "E:\eCommerce_Projects\remote-hospital-v3\venv\lib\site-packages\rest_framework\decorators.py", line 50, in handler
return func(*args, **kwargs)
File "E:\eCommerce_Projects\remote-hospital-v3\panel\views\appointment_views.py", line 19, in makeAppointments
membersToHeldMeeting = data['membersToHeldMeeting']
KeyError: 'membersToHeldMeeting'
[17/Jul/2021 23:52:27] "POST /api/appointment/make/ HTTP/1.1" 500 106441
First take a look at backend
urls
path('api/appointment/make/', views.makeAppointments, name='appointment-add'),
Related view
#api_view(['POST'])
#permission_classes([IsAuthenticated])
def makeAppointments(request):
user = request.user
data = request.data
membersToHeldMeeting = data['membersToHeldMeeting']
if membersToHeldMeeting and len(membersToHeldMeeting) == 0:
return Response({'detail': 'No Appointment Has Been Set'}, status=status.HTTP_400_BAD_REQUEST)
else:
# (1) Create Appointment
createappointment = MakeAppointment.objects.create(
user=user,
reasonOfAppointment=data['reasonOfAppointment'],
meetingWillBeConductedOn=data['meetingWillBeConductedOn'],
paymentMethod=data['paymentMethod'],
taxPrice=data['taxPrice'],
consultancyServiceFee=data['consultancyServiceFee'],
totalFee=data['totalFee']
)
# (2) Create AppointmentDetails
appointmentdetails = AppointmentDetails.objects.create(
appointment=appointment,
appointmentReason=data['appointmentDetails']['appointmentReason'],
dateOfBirth=data['appointmentDetails']['dateOfBirth'],
gender=data['appointmentDetails']['gender'],
maritalStatus=data['appointmentDetails']['maritalStatus'],
phoneNumber=data['appointmentDetails']['phoneNumber'],
emergencyContactNo=data['appointmentDetails']['emergencyContactNo'],
medicalHistory=data['appointmentDetails']['medicalHistory'],
previousTreatmentDetails=data['appointmentDetails']['previousTreatmentDetails'],
allergicTo=data['appointmentDetails']['allergicTo'],
address=data['appointmentDetails']['address'],
city=data['appointmentDetails']['city'],
postalCode=data['appointmentDetails']['postalCode'],
country=data['appointmentDetails']['country'],
)
# (3) Create all appointments and set appointment to MembersOfPanelToHeldMeeting relationship
for i in allAppointments:
panelmember = PanelMember.objects.get(_id=i['panelmember'])
allmeetings = MembersOfPanelToHeldMeeting.objects.create(
panel=panel,
appointment=appointment,
name=panelmember.name,
totalFee=i[''],
image=panelmember.image.url,
)
serializer = MakeAppointmentSerializer(createappointment, many=False)
return Response(serializer.data)
serializer.py
class AppointmentDetailsSerializer(serializers.ModelSerializer):
class Meta:
model = AppointmentDetails
fields = '__all__'
class MembersOfPanelToHeldMeetingSerializer(serializers.ModelSerializer):
class Meta:
model = MembersOfPanelToHeldMeeting
fields = '__all__'
class MakeAppointmentSerializer(serializers.ModelSerializer):
membersToHeldMeeting = serializers.SerializerMethodField(read_only=True)
appointmentDetailsFromSerilizer = serializers.SerializerMethodField(read_only=True)
user = serializers.SerializerMethodField(read_only=True)
class Meta:
model = MakeAppointment
fields = '__all__'
def get_membersToHeldMeeting(self, obj):
members = obj.membersofpaneltoheldmeeting_set.all()
serializer = MembersOfPanelToHeldMeetingSerializer(members, many=True)
return serializer.data
def get_appointmentDetails(self, obj):
try:
details = AppointmentDetailsSerializer(
obj.appointmentDetailsFromSerilizer, many=False).data
except:
details = False
return details
def get_user(self, obj):
user = obj.user
serializer = UserSerializer(user, many=False)
return serializer.data
Now take a look into react side
actions.js
export const createAppointment = (appointment) => async (dispatch, getState) => {
try {
dispatch({
type: MEETING_CREATE_REQUEST
})
const {
userLogin: { userInfo },
} = getState()
const config = {
headers: {
'Content-type': 'application/json',
Authorization: `Bearer ${userInfo.token}`
}
}
const { data } = await axios.post(
`/api/appointment/make/`,
appointment,
config
)
dispatch({
type: MEETING_CREATE_SUCCESS,
payload: data
})
dispatch({
type: MEETINGS_CART_PANEL_MEMBERS_CLEAR,
payload: data
})
localStorage.removeItem('meetingConductingMembers')
} catch (error) {
dispatch({
type: MEETING_CREATE_FAIL,
payload: error.response && error.response.data.detail
? error.response.data.detail
: error.message,
})
}
}
reducers.js
export const meetingCreateReducer = (state = {}, action) => {
switch (action.type) {
case MEETING_CREATE_REQUEST:
return {
loading: true
}
case MEETING_CREATE_SUCCESS:
return {
loading: false,
success: true,
order: action.payload
}
case MEETING_CREATE_FAIL:
return {
loading: false,
error: action.payload
}
case MEETING_CREATE_RESET:
return {}
default:
return state
}
}
I'm pushing data as .
const placeAppointment = () => {
dispatch(
createAppointment({
membersToHeldMeeting: meetingsConductingCart.membersToHeldMeeting,
appointmentDetails: meetingsConductingCart.appointmentDetails, //this seem not accurate
paymentMethod: meetingsConductingCart.paymentMethod,
reasonOfAppointment: meetingsConductingCart.appointmentReason,
taxPrice: meetingsConductingCart.taxPrice,
consultancyServiceFee: meetingsConductingCart.consultancyServiceFee,
totalFee: meetingsConductingCart.totalFee,
})
);
dispatching this I get
KeyError: 'membersToHeldMeeting'
[18/Jul/2021 10:43:28] "POST /api/appointment/make/ HTTP/1.1" 500 106441
Can you Identify where the problem would be and how to fix this. thanx
Solved.
I wasn't constructing the data correctly at frontend for POST request
Problem was on fronted
const placeAppointment = () => {
dispatch(
createAppointment({
membersToHeldMeeting: meetingsConductingCart.meetingConductingMembers, #this line was changed for that exact error.
appointmentDetails: meetingsConductingCart.appointmentDetails,
paymentMethod: meetingsConductingCart.meetingsPaymentMethod,
reasonOfAppointment:
meetingsConductingCart.appointmentDetails.appointmentReason,
meetingWillBeConductedOn:
meetingsConductingCart.appointmentDetails.meetingWillBeConductedOn,
taxPrice: meetingsConductingCart.taxPrice,
consultancyServiceFee: meetingsConductingCart.consultancyServiceFee,
totalFee: meetingsConductingCart.grandtotalFee,
})

I'm trying to apply celery to Class based view(apis) in django. How can I do this?

Is it a correct way to apply celery to class based views?
And, if it is, how can I apply celery to class based Views?
I can’t apply just tagging #app.task above functions inside class.
class ScheduleByFranchiseIdView(generics.RetrieveAPIView):
permission_classes = (IsAdmin,)
serializer_class = ScheduleSerializer
#app2.task
def get(self, request, franchise_id, start = None, end = None):
if start != None and end != None:
query1 = Q(student__profile__franchise__exact=franchise_id)
query2 = Q(start_time__gte=start)
query3 = Q(end_time__lt=end)
queryset = Schedule.objects.filter(query1 & query2 & query3).exclude(status=ScheduleStatus.DELETED).order_by('-id')
serializer = ScheduleSerializer(queryset, many=True)
else:
query1 = Q(student__profile__franchise__exact=franchise_id)
queryset = Schedule.objects.filter(query1).exclude(status=ScheduleStatus.DELETED).order_by('-id')
serializer = ScheduleSerializer(queryset, many=True)
return Response(serializer.data)
I'm trying to test this api and when I call HTTP GET Method to call this api,
i get the error below:
Traceback (most recent call last):
File "C:\Users\Tonyscoding\Desktop\TOCOL\TOCOL_backend\api\testing\test_pagination.py", line 154, in test_admin_schedule_pagination
response = self.client.get('/api/schedule/by/franchise/simple/1/')
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\test.py", line 286, in get
response = super().get(path, data=data, **extra)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\test.py", line 203, in get
return self.generic('GET', path, **r)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\test.py", line 232, in generic
method, path, data, content_type, secure, **extra)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\test\client.py", line 422, in generic
return self.request(**r)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\test.py", line 283, in request
return super().request(**kwargs)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\test.py", line 235, in request
request = super().request(**kwargs)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\test\client.py", line 503, in request
raise exc_value
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_exception
raise exc
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\celery\local.py", line 191, in __call__
return self._get_current_object()(*a, **kw)
File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\celery\app\task.py", line 392, in __call__
return self.run(*args, **kwargs)
TypeError: get() missing 1 required positional argument: 'request'
my celery worker get the task. I think it's not a worker problem..
In your case might work next scenario. Create a task for hard workload:
#app.task
def schedule_by_franchise(franchise_id, start=None, end=None):
# Do some slow workload, filtering by non-indexed fields or something.
if start is not None and end is not None: # is not None ~20% faster than != None
query1 = Q(student__profile__franchise__exact=franchise_id)
query2 = Q(start_time__gte=start)
query3 = Q(end_time__lt=end)
queryset = Schedule.objects.filter(query1 & query2 & query3).exclude(status=ScheduleStatus.DELETED).order_by('-id')
else:
query1 = Q(student__profile__franchise__exact=franchise_id)
queryset = Schedule.objects.filter(query1).exclude(status=ScheduleStatus.DELETED).order_by('-id')
# Returns something serializable and what could be used for more faster DB search (founded object primary keys might fits)
return tuple(queryset.values_list('id', flat=True))
When executed first GET you should create Celery task and then save it TASK_ID somewhere to later get result:
from celery.result import AsyncResult
class ScheduleByFranchiseIdView(generics.RetrieveAPIView):
permission_classes = (IsAdmin,)
serializer_class = ScheduleSerializer
def get(self, request, franchise_id, start=None, end=None, task_id=None):
if not task_id:
task = schedule_by_franchise.delay(franchise_id, start, end)
return Response({
'task': task.task_id,
'status': 'processing',
'message': f'Please, try again in 10 seconds with following task_id={task.task_id}',
})
else:
result = AsyncResult(task_id)
if result.ready():
ids = result.result
queryset = Schedule.objects.filter(id__in=ids)
serializer = ScheduleSerializer(queryset, many=True)
return Response(serializer.data)
else:
return Response({
'status': 'not_ready_yet',
'message': 'Please, try again in 5 seconds',
})

Django AttributeError: 'collections.OrderedDict' object has no attribute 'pk'

When I try to add an url attribute to my model I get this error:
AttributeError: 'collections.OrderedDict' object has no attribute 'pk'
These are the codes I use. I tried a lot of things but just get an error with everything I try..
Serializer:
class GroupPatchSerializer(serializers.ModelSerializer):
linked_sites = serializers.ListField()
name = serializers.CharField(required=False)
url = serializers.HyperlinkedIdentityField(
view_name="group-detail", lookup_url_kwarg="group_pk"
)
class Meta:
model = Group
fields = ("id", "url", "name", "linked_sites")
def validate_linked_sites(self, sites):
** code **
return sites
# noinspection PyMethodMayBeStatic
def validate_name(self, name):
** code **
return name
view:
def patch(self, request, group_pk):
"""
Add site to group, change an existing group's name.
-id: The group's id
"""
user = request.user
group_id = int(group_pk)
group = Group.objects.filter(pk=group_id).first()
# Update the group
serializer_class = self.get_serializer_class()
serializer = serializer_class(
data=self.request.data,
context={"request": request, "user_pk": user.id, "group_id": group_id},
)
test-class:
def test_ok_authorized_access(self):
# Login the user
self.client.force_login(self.user_1)
UserSiteFactory(user=self.user_1, site=self.test_site_3)
# Get the url
url = reverse("group-detail", kwargs={"group_pk": self.test_group_1.pk})
# New group name
new_name = "New group name"
sites = [self.test_site_3.pk]
# Execute the patch operation
response = self.client.patch(
url, data={"name": new_name, "linked_sites": sites}
)
# Test if there was no error
self.assertEqual(response.status_code, status.HTTP_200_OK)
# Test if the group was renamed
group = Group.objects.all().filter(pk=self.test_group_1.pk).first()
self.assertEqual(group.name, new_name)
stacktrace
Traceback (most recent call last):
File "/opt/project/backend/groups/tests/test_group_patch.py", line 45, in test_ok_authorized_access
url, data={"name": new_name, "linked_sites": sites}
File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 310, in patch
path, data=data, format=format, content_type=content_type, **extra)
File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 215, in patch
return self.generic('PATCH', path, data, content_type, **extra)
File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 232, in generic
method, path, data, content_type, secure, **extra)
File "/usr/local/lib/python3.6/site-packages/django/test/client.py", line 422, in generic
return self.request(**r)
File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 283, in request
return super().request(**kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 235, in request
request = super().request(**kwargs)
File "/usr/local/lib/python3.6/site-packages/django/test/client.py", line 503, in request
raise exc_value
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/viewsets.py", line 114, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
raise exc
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "/opt/project/backend/groups/views/group_detail_view.py", line 108, in patch
return Response(serializer.data, status=status.HTTP_200_OK)
File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 559, in data
ret = super().data
File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 263, in data
self._data = self.to_representation(self.validated_data)
File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 526, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/usr/local/lib/python3.6/site-packages/rest_framework/relations.py", line 393, in to_representation
url = self.get_url(value, self.view_name, request, format)
File "/usr/local/lib/python3.6/site-packages/rest_framework/relations.py", line 329, in get_url
lookup_value = getattr(obj, self.lookup_field)
AttributeError: 'collections.OrderedDict' object has no attribute 'pk'
From the DRF docs on HyperlinkedIdentityField:
lookup_field - The field on the target that should be used for the lookup. Should correspond to a URL keyword argument on the referenced view. Default is 'pk'.
lookup_url_kwarg - The name of the keyword argument defined in the URL conf that corresponds to the lookup field. Defaults to using the same value as lookup_field.
So you're setting lookup_url_kwarg directly, but you're not changing lookup_field, which is where your error is coming from. Because lookup_url_kwarg defaults to the same value as lookup_field, we can just use that:
class GroupPatchSerializer(serializers.ModelSerializer):
# code...
url = serializers.HyperlinkedIdentityField(
view_name="group-detail", lookup_field="group_pk"
)
# code...

Django TypeError: sequence item 0: expected str instance, NoneType found

I tried sending email through smtp and email.mime with Django. I have decided not to use the django email because I want to automate sending of emails to several other emails from any user so the user will be required to put in his email and password to his gmail so smtp can send emails using his account to other emails
Internal Server Error: /api/email/1/send/
Traceback (most recent call last):
File "/home/taycode/Desktop/emailsenderapi/env/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/taycode/Desktop/emailsenderapi/env/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/taycode/Desktop/emailsenderapi/env/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/taycode/Desktop/emailsenderapi/env/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/taycode/Desktop/emailsenderapi/env/lib/python3.6/site-packages/django/views/generic/base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "/home/taycode/Desktop/emailsenderapi/env/lib/python3.6/site-packages/rest_framework/views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "/home/taycode/Desktop/emailsenderapi/env/lib/python3.6/site-packages/rest_framework/views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/taycode/Desktop/emailsenderapi/env/lib/python3.6/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
raise exc
File "/home/taycode/Desktop/emailsenderapi/env/lib/python3.6/site-packages/rest_framework/views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "/home/taycode/Desktop/emailsenderapi/api/views.py", line 71, in post
serializer.send(email_object_id=pk, validated_data=serializer.validated_data)
File "/home/taycode/Desktop/emailsenderapi/api/serializers.py", line 61, in send
sender.send()
File "/home/taycode/Desktop/emailsenderapi/api/utils.py", line 44, in send
self.s.send_message(msg=self.msg)
File "/usr/lib/python3.6/smtplib.py", line 936, in send_message
from_addr = email.utils.getaddresses([from_addr])[0][1]
File "/usr/lib/python3.6/email/utils.py", line 112, in getaddresses
all = COMMASPACE.join(fieldvalues)
TypeError: sequence item 0: expected str instance, NoneType found
This is my sender class which I created
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.text import MIMEText
from os.path import basename
class Sender:
def __init__(self, email, password):
host = "smtp.gmail.com"
port = 587
self.email = email
self.s = smtplib.SMTP(host=host, port=port)
self.s.starttls()
self.s.login(email, password)
self.msg = MIMEMultipart()
def add_attachments(self, path):
with open(path, "rb") as fil:
part = MIMEApplication(
fil.read(),
Name=basename(path)
)
# After the file is closed
part['Content-Disposition'] = 'attachment; filename="%s"' % basename(path)
self.msg.attach(part)
def add_body(self, body):
self.msg.attach(MIMEText(body, "plain"))
return self.msg
def add_recipient(self, email):
self.msg['To'] = email
return self.msg
def add_subject(self, subject):
self.msg['subject'] = subject
return self.msg
def send(self):
print(dict(self.msg))
print(self.s)
self.s.send_message(msg=self.msg)
del self.msg
self.s.quit()
this is my serializer.py
from sender.models import EmailObject
from .utils import Sender
class SendEmailSerializer(Serializer):
email = serializers.EmailField()
password = serializers.CharField()
#staticmethod
def send(validated_data, **kwargs):
email_object = EmailObject.objects.get(pk=kwargs['email_object_id'])
for recipient in email_object.recipient.all():
sender = Sender(validated_data['email'], validated_data['password'])
sender.add_recipient(str(recipient.email))
sender.add_body(email_object.body)
sender.add_subject(email_object.subject)
for attachment in email_object.attachments.all():
print(attachment.file.path)
sender.add_attachments(attachment.file.path)
sender.send()
This is my views.py
class SendEmail(APIView):
serializer_class = SendEmailSerializer
#staticmethod
def post(request, pk):
serializer = SendEmailSerializer(data=request.data)
if serializer.is_valid():
print(serializer.validated_data)
serializer.send(email_object_id=pk, validated_data=serializer.validated_data)
data = {'status': 'success'}
return Response(data, status=status.HTTP_200_OK)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
It returns error everytime I call the SendEmail view in views.py.
how can I fix this??
smtplib.SMTP().send_messages takes 3 parameters, from, to and message. In your code, you are only sending message to the moethod. You need to replace self.s.send_message(msg=self.msg) with:
self.s.send_message(self.email, self.msg['To'], self.msg.as_string())

to_representation error: 'NoneType' object is not iterable

I'm attempting to update DRF transform_<name> to use the new to_representation method. When I try to do this I'm getting the following error that I'm finding hard to track down. I have tested this on all my serializers and I get the same thing:
Traceback (most recent call last):
File "/Users/glyn/Documents/workspace/app/django-env/lib/python2.7/site-packages/django/core/handlers/base.py", line 111, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/glyn/Documents/workspace/app/django-env/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 57, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/glyn/Documents/workspace/app/django-env/lib/python2.7/site-packages/django/views/generic/base.py", line 69, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/glyn/Documents/workspace/app/django-env/lib/python2.7/site-packages/rest_framework/views.py", line 407, in dispatch
response = self.handle_exception(exc)
File "/Users/glyn/Documents/workspace/app/django-env/lib/python2.7/site-packages/rest_framework/views.py", line 404, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/glyn/Documents/workspace/app/app/apps/ornamentation/views/photo.py", line 23, in get
return self.retrieve(request, *args, **kwargs)
File "/Users/glyn/Documents/workspace/app/django-env/lib/python2.7/site-packages/rest_framework/mixins.py", line 56, in retrieve
return Response(serializer.data)
File "/Users/glyn/Documents/workspace/app/django-env/lib/python2.7/site-packages/rest_framework/serializers.py", line 464, in data
return ReturnDict(ret, serializer=self)
File "/Users/glyn/Documents/workspace/app/django-env/lib/python2.7/site-packages/rest_framework/utils/serializer_helpers.py", line 14, in __init__
super(ReturnDict, self).__init__(*args, **kwargs)
File "/usr/local/Cellar/python/2.7.8_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/collections.py", line 52, in __init__
self.__update(*args, **kwds)
File "/Users/glyn/Documents/workspace/app/django-env/bin/../lib/python2.7/_abcoll.py", line 566, in update
for key, value in other:
TypeError: 'NoneType' object is not iterable
My code:
class ThumbnailSerializerMixin(serializers.HyperlinkedModelSerializer):
"""
Mixin used to create a thumbnail based on parameters.
If no parameters have been passed defaults are used.
"""
thumbnail_image = HyperlinkedImageField()
thumbnail = HyperlinkedImageField()
def to_representation(self, instance):
super(PhotoThumbnailSerializer,self).to_representation(instance)
def transform_thumbnail(self, obj, value):
"""
:param: thumbnail_width, thumbnail_height, thumbnail_quality,
:return: S3 signed URL to thumbnail.
"""
if not value == "null":
width = self.context['request'].GET.get('thumbnail_width', settings.THUMBNAIL_DEFAULT_WIDTH)
height = self.context['request'].GET.get('thumbnail_height', settings.THUMBNAIL_DEFAULT_HEIGHT)
quality = self.context['request'].GET.get('thumbnail_quality', settings.THUMBNAIL_DEFAULT_QUALITY)
return urllib.quote(obj.thumbnail(width=width, height=height, quality=quality).url, safe="%/:=&?~#+!$,;'#()*[]")
return "null"
class Meta:
abstract = True
fields = ("url", "thumbnail_image", "thumbnail",)
class PhotoThumbnailSerializer(ThumbnailSerializerMixin):
url = serializers.HyperlinkedIdentityField(view_name='photo_detail')
raw_image = HyperlinkedImageField()
class Meta(ThumbnailSerializerMixin.Meta):
model = Photo
fields = ("url", "raw_image", "thumbnail",)
Note: above I have left in transform_thumbnail which is my old method. Adding in the to_representation method generates the error.
your to_representation method can't return null value. you forgot return statement.
def to_representation(self, instance):
return super(PhotoThumbnailSerializer,self).to_representation(instance)

Categories