Home > Blockchain >  Django / Python - change does not save in database - AttributeError: 'QuerySet' object has
Django / Python - change does not save in database - AttributeError: 'QuerySet' object has

Time:03-25

I have a setting that a user can change: send email automatically or manually. For this, I created a database with only 1 row that has the following columns:

class AutoSendMail(models.Model):
    auto = models.BooleanField(default=False)
    manual = models.BooleanField(default=True)
    send_type = (
        ('manual', 'MANUAL'),
        ('auto', 'AUTO')
    )
    type = models.CharField(max_length=6, choices=send_type, default="manual")

    def get(self):
        new_self = self.__class__.objects.get(pk=self.pk)
        # You may want to clear out the old dict first or perform a selective merge
        self.__dict__.update(new_self.__dict__)
        return reverse("core:autosend", kwargs={"auto": self.auto})

    def reload(self):
        new_self = self.__class__.objects.get(pk=self.pk)
        # You may want to clear out the old dict first or perform a selective merge
        self.__dict__.update(new_self.__dict__)

In this, either 'auto' or 'manual' is True, and the other one is False. The 'type' is set to 'auto' or 'manual' accordingly. This setting is used in the rest of the code. The code I have now in my view is:

class AutoSendView(generic.TemplateView):

    template_name = 'core/mailbox/autoSendMail.html'
    context_object_name = 'autosend'
    extra_context = {"mailbox_page": "active"}

    model = AutoSendMail.objects.get(id=1)
    model.refresh_from_db()

    autoSetting = int(model.auto == True)
    manualSetting = int(model.manual == True)

    def post(self, request, *args, **kwargs):
        id_ = self.kwargs.get("pk")
        update_type = self.request.POST.get('update_type')

        if update_type == 'manual':
            logger.info("Set to: manual email send")
            model = AutoSendMail.objects.filter(id=1)
            model.manual = True
            model.auto = False
            model.type = "manual"
            for object in model:
                object.save()
                model.reload()

            return redirect("core:autosend")

        elif update_type == 'auto':
            logger.info("Set to: auto email send")
            model = AutoSendMail.objects.filter(id=1)
            model.manual = False
            model.auto = True

            model.type = "auto"
            for object in model:
                object.save()
                model.reload()

            return redirect("core:autosend")

My problem is that what a user changes in the setting is not saved in the database (sqlite3). And I'm not sure why not. Because when I try this in my python console, it does work. So I do something wrong.

With the code above I get an error saying:

ERROR Internal Server Error: /mailbox/autosend
Traceback (most recent call last):
  File "C:\Users\Portal\venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\Portal\venv\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Portal\venv\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "C:\Users\Portal\venv\lib\site-packages\django\views\generic\base.py", line 69, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\Portal\venv\lib\site-packages\django\views\generic\base.py", line 101, in dispatch
    return handler(request, *args, **kwargs)
  File "C:\Users\portal\core\views.py", line 200, in post
    model.reload()
AttributeError: 'QuerySet' object has no attribute 'reload'
ERROR "POST /mailbox/autosend HTTP/1.1" 500 2657

Someone has an idea how to deal with this? When I remove the 'reload' it gives the error 'QuerySet' object has no attribute 'save'. If I remove the 'save()' also, it does not save the change

CodePudding user response:

filter(...) will return a Queryset, but get(...) returns the object. So replace:

model = AutoSendMail.objects.filter(id=1)

with

model = AutoSendMail.objects.get(id=1)

Alternate

I think your codes are very redundant and unoptimized. I think you can use the following code:

if update_type == 'auto':
    model = AutoSendMail.objects.filter(id=1).update(type="auto", auto=True)
  • Related