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)