Django 'int' object is not iterable when trying to update objects in views - python-3.x

I am getting this error when trying to update objects from False to True. here is my code:
class ListNoti(LoginRequiredMixin,ListView):
raise_exception = True
model = Notifications
template_name = 'notifications/notifications.html'
def get_context_data(self, **kwargs):
data = super(ListNoti,self).get_context_data(**kwargs)
data['noti'] = Notifications.objects.filter(receiver=self.request.user,is_seen=False).order_by('-date').update(is_seen=True)
return data
.update(is_seen=True) raising this error TypeError at /notification/ 'int' object is not iterable

I solved this issue after using queryset in my views. here is my full code:
class ListNoti(LoginRequiredMixin,ListView):
raise_exception = True
model = Notifications
template_name = 'notifications/notifications.html'
def get_queryset(self):
data = Notifications.objects.filter(receiver=self.request.user).update(is_seen=True)
return data
def get_context_data(self, **kwargs):
data = super(ListNoti,self).get_context_data(**kwargs)
data['noti'] = Notifications.objects.filter(receiver=self.request.user)
return data

Related

Trying to show created date of order on another view i get KeyERROR "list_id"

Been trying to show the created_date of the customer order on another view, kindly help much appreciated.
ListListView
class ListListView(generic.ListView):
model = HBTYList
template_name = "accounts/modals/nomodal/index.html"
paginate_by = 3
def get_queryset(self):
qs = self.model.objects.all().order_by('-id')
p_f = HbtyCustomerListFilter(self.request.GET, queryset=qs)
return p_f.qs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['dc'] = HBTYItem.objects.filter(hbty_cust_id=self.kwargs["list_id"]) #Fix this method to show created_data
context['filter'] = HbtyCustomerListFilter(self.request.GET, queryset=self.get_queryset())
return context
ItemListView
class ItemListView(ListView):
model = HBTYItem
template_name = "accounts/modals/nomodal/todo_list.html"
paginate_by = 2
ordering = ['id']
def get_queryset(self):
return HBTYItem.objects.filter(hbty_cust_id=self.kwargs["list_id"])
def get_context_data(self):
context = super().get_context_data()
context['t_sum'] = HBTYItem.objects.filter(hbty_cust_id=self.kwargs["list_id"]).aggregate(Sum('price'))
context["hbty_list"] = HBTYList.objects.get(id=self.kwargs["list_id"])
return context
Urls.py
path("hbtylist/", views.ListListView.as_view(), name="hbtylist"),
path("list/<int:list_id>/", views.ItemListView.as_view(), name="list"),
# CRUD URL FOR HBTYCUSTOMERS
path("list/add/", views.ListCreate.as_view(), name="list-add"),
path("list/<int:pk>/delete/", views.ListDelete.as_view(), name="list-delete"),
# CRUD URL FOR HBTYCUSTOMERSAPPOINMENTS
path("list/<int:list_id>/item/add/", views.ItemCreate.as_view(),name="item-add",),
path("list/<int:list_id>/item/<int:pk>/",views.ItemUpdate.as_view(),name="item-update",),
path("list/<int:list_id>/item/<int:pk>/delete/",views.ItemDelete.as_view(),name="item-delete",),
Thank You For The Help.

field_name = ordering[0].lstrip('-') throws IndexError: tuple index out of range in DRF rest_framework\pagination.py

I am getting error IndexError: tuple index out of range while using CursorPagination of DRF.
my code-
class CursorSetPagination(CursorPagination):
page_size = 10
page_size_query_param = 'page_size'
ordering = '-created_at'
class WalletCreditViewset(viewsets.ReadOnlyModelViewSet):
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated]
pagination_class = CursorSetPagination
serializer_class = WalletCreditSerializer
def get_queryset(self):
queryset = PaymentOrder.objects.filter(user=self.request.user)
return queryset
The errors comes when the entry in the database table for a particular user cross the value of page_size.
Ex- if some user have 5 payment order then there will be no error but when the same user cross 10 payment order then this error occurs.
I think you must order data in queryset, not in pagination.
for example:
class CursorSetPagination(CursorPagination):
page_size = 10
page_size_query_param = 'page_size'
class WalletCreditViewset(viewsets.ReadOnlyModelViewSet):
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated]
pagination_class = CursorSetPagination
serializer_class = WalletCreditSerializer
def get_queryset(self):
queryset = PaymentOrder.objects.filter(user=self.request.user).order_by("-created_at")
return queryset

Django Rest Framework - to_internal_value Error Inconsistency

I have a model, User, in which the primary unique field is email. I have a separate Organization model which allows users to map to organizations through a many-to-many mapping.
I want the serializer to allow users to be created if they have an existing email but no organization association (organization is taken from the user making the request so is not in the payload).
The standard ModelSerializer includes a check against the field in to_internal_value(). I am consequently trying to override it like so:
def to_internal_value(self, data):
"""
Dict of native values <- Dict of primitive datatypes.
"""
fields = self._writable_fields
for field in fields:
validate_method = getattr(self, 'validate_' + field.field_name, None)
primitive_value = field.get_value(data)
try:
if validate_method == self.validate_email:
if User.objects.filter(email=primitive_value).exists():
if not self.active_organization.members.filter(email=primitive_value).exists():
continue
else:
validated_value = field.run_validation(primitive_value)
if validate_method is not None:
validated_value = validate_method(validated_value)
except ValidationError as exc:
errors[field.field_name] = exc.detail
except DjangoValidationError as exc:
errors[field.field_name] = get_error_detail(exc)
except SkipField:
pass
else:
set_value(ret, field.source_attrs, validated_value)
return super().to_internal_value(data)
This works, but the error that is returned if the object already has a record in User and Organization does not correctly map as a dictionary. For example, the validation error shows this:
[ErrorDetail(string='User with this Email already exists.', code='unique')]
Instead of what it should show, this:
{'email': [ErrorDetail(string='User with this Email already exists.', code='unique')]}
I tested by overriding the method and trying both my custom called code vs. the original, and it replicates the above findings:
def to_internal_value(self, data):
"""
Dict of native values <- Dict of primitive datatypes.
"""
try:
print('trying custom')
for field in self._writable_fields:
if field.field_name == 'email':
print(field.run_validation)
validated_value = field.run_validation(field.get_value(data))
except Exception as e:
print('error custom')
print(str(e))
try:
print('Trying original')
value = super().to_internal_value(data)
except Exception as e:
print('Exception - original')
print(str(e))
Output:
trying custom
<bound method CharField.run_validation of EmailField(max_length=254, validators=[<UniqueValidator(queryset=User.objects.all())>])>
error custom
[ErrorDetail(string='User with this Email already exists.', code='unique')]
Trying original
Exception - original
{'email': [ErrorDetail(string='User with this Email already exists.', code='unique')]}
Can anyone help me understand why this is happening please? I'm really stuck as to how this is happening.
I was not able to figure out why exactly the errors generated by to_internal_value(self, data) change when I copy the code from the underlying ModelSerializer vs calling super(). However, I did find a kind-of hackish workaround.
Because I strip out all the other related info (nested serializers, kind of) before hand, I'm really just worried about the email. Therefore, I traverse the _writable_fields twice: the first time I look for an existing email where it isn't in the organization. If those conditions are true, I return a dictionary and proceed to the create() method. If they fail, I call super. So far this seems to work. Here is my simplified class.
def to_internal_value(self, data):
"""
Dict of native values <- Dict of primitive datatypes.
"""
try:
for field in self._writable_fields:
if field.field_name == 'email':
primitive_value = field.get_value(data)
validator = EmailValidator()
validator(primitive_value)
if User.objects.filter(email=primitive_value).exists():
if not self.active_organization.members.filter(email=primitive_value).exists():
self.email_already_exists = True
return {'email': primitive_value}
except:
pass
return super().to_internal_value(data)
For reference, this is the complete ViewSet and Serializer I'm using:
class AdminUsersSerializer(serializers.ModelSerializer):
"""User serializer for the admin user view"""
groups = GenericGroupSerializer(source='group_set', many=True, required=False)
permission_sets = GenericPermissionSetSerializer(source='permissionset_set', many=True, required=False)
active_organization = None
email_already_exists = False
class Meta:
model = User
fields = ['pk', 'email', 'groups', 'permission_sets'] # , 'permissions']
def set_active_organization(self, organization):
self.active_organization = organization
def create(self, validated_data):
if not self.email_already_exists:
user = User.objects.create(
email=validated_data['email']
)
user.set_password(None)
user.save()
else:
user = User.objects.get(email=validated_data['email'])
return user
def to_internal_value(self, data):
"""
Dict of native values <- Dict of primitive datatypes.
"""
try:
for field in self._writable_fields:
if field.field_name == 'email':
primitive_value = field.get_value(data)
validator = EmailValidator()
validator(primitive_value)
if User.objects.filter(email=primitive_value).exists():
if not self.active_organization.members.filter(email=primitive_value).exists():
self.email_already_exists = True
return {'email': primitive_value}
except:
pass
return super().to_internal_value(data)
class AdminUsersViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = AdminUsersSerializer
permission_classes = [account_permissions.IsAdminRequired]
http_method_names = ['get', 'post']
active_organization = None
def create(self, request, *args, **kwargs):
self.active_organization = self.request.user.activeorganization.organization
groups = None
permission_sets = None
serializer = self.get_serializer(data=request.data)
serializer.set_active_organization(self.active_organization)
if 'groups' in serializer.initial_data:
if serializer.initial_data.get('groups'):
groups = serializer.initial_data.pop('groups')
else:
serializer.initial_data.pop('groups')
if 'permission_sets' in serializer.initial_data:
if serializer.initial_data.get('permission_sets'):
permission_sets = serializer.initial_data.pop('permission_sets')
else:
serializer.initial_data.pop('permission_sets')
# Normal method functions
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
# Created user
user = User.objects.get(email=serializer.data['email'])
# Add user to organization
self.active_organization.members.add(user)
# Make sure to format the ajax groups data properly
if groups:
try:
group = Group.objects.get(
id=groups,
organization=self.active_organization
)
group.members.add(user)
except:
pass
if permission_sets:
try:
permission_set = PermissionSet.objects.get(
id=permission_sets,
organization=self.active_organization
)
permission_set.members.add(user)
except:
pass
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def get_queryset(self):
return self.queryset.filter(
userorganizationmembership__organization=self.request.user.activeorganization.organization
).all()
It does feel hackish, but it seems to be getting the job done.

Python3 super not initializing __init__ attributes

I have the following code snippet:
class BaseUserAccount(object):
def __init__(self):
accountRefNo = "RefHDFC001"
FIType = "DEPOSIT"
pan = "AFF34964FFF"
mobile = "9822289017"
email = "manoja#cookiejar.co.in"
aadhar = "5555530495555"
class TestUserSavingsAccount(BaseUserAccount):
def __init__(self):
super().__init__()
accountNo = "HDFC111111111111"
accountTypeEnum = "SAVINGS"
def test_create_account(self):
request_body = """\
<UserAccountInfo>
<UserAccount accountRefNo="{}" accountNo="{}"
accountTypeEnum="{}" FIType="{}">
<Identifiers pan="{}" mobile="{}" email="{}" aadhar="{}"></Identifiers>
</UserAccount>
</UserAccountInfo>
""".format(self.accountRefNo, self.accountNo, self.accountTypeEnum,
self.FIType, self.pan, self.mobile, self.email, self.aadhar)
If I run this code in the interactive shell:
>>> t = TestUserSavingsAccount()
>>> t.accountRefNo
AttributeError: 'TestUserSavingsAccount' object has no attribute 'accountRefNo'
>>> t.accountNo
AttributeError: 'TestUserSavingsAccount' object has no attribute 'accountNo'
Seeing the above behavior, it seems like the super is neither setting up values from the base class and neither the attributes of the child (accountNo, accountTypeEnum) are being set.
The way you wrote only assign those values to local variables. You need to initialize attributes of the self object instead:
class BaseUserAccount(object):
def __init__(self):
self.accountRefNo = "RefHDFC001"
self.FIType = "DEPOSIT"
self.pan = "AFF34964FFF"
self.mobile = "9822289017"
self.email = "manoja#cookiejar.co.in"
self.aadhar = "5555530495555"
class TestUserSavingsAccount(BaseUserAccount):
def __init__(self):
super().__init__()
self.accountNo = "HDFC111111111111"
self.accountTypeEnum = "SAVINGS"

AttributeError: 'DB_Connector' object has no attribute 'cursor'

I'm a newbie to python and trying to create a class object for a database connection. I seem to be running into trouble when trying to access a variable from one function that was created in another function inside the class. Is this possible or am I going about it the wrong way? The code errors on the last line: db_results = oyn_conn.Execute(query) with an AttributeError listed in the heading
class DB_Connector(object):
def __init__(self, user,passwd,db):
self.user = user
self.passwd = passwd
self.db = db
self.CreateConnection
def CreateConnection(self):
self.cursor = mysql.connector.connect(user=self.user,password = self.password,database= self.db)
def Execute(self, sql_statement):
self.cursor.execute(sql_statement)
return self.cursor.fetchall()
query = "select venue_name,venue_id from venue where venue_id in('1435','345')"
oyn_conn = DB_Connector('root','password','oyn_db')
db_results = oyn_conn.Execute(query)
Ok So I played around with it and found the answer, I had some sytax errors in my code:
class DB_Connector(object):
def __init__(self, user,passwd,db):
self.user = user
self.passwd = passwd
self.db = db
self.CreateConnection()
def CreateConnection(self):
self.cnx = mysql.connector.connect(user=self.user,passwd = self.passwd,database= self.db)
self.cursor = self.cnx.cursor()
self.cnx._open_connection()
def Execute(self, sql_statement):
self.cursor.execute(sql_statement)
return self.cursor.fetchall()
def DestroyConnection(self):
self.cursor.close()
query = "select venue_name,venue_id from venue where venue_id
in('1332343501255','1888841136809')"
oyn_conn = DB_Connector('root','password','oyn_db')
db_results = oyn_conn.Execute(query)
print(db_results)
oyn_conn.DestroyConnection()

Resources