Wenze Wenze - 3 months ago 11
Python Question

Creating a Django demo-user who can't save to the database

I'm creating a Django web application on which users can create an account for free. I have also set-up a demo user which is already configured and has data attached to its account. Purpose of this demo account is to give a new user a quick overview of what the application can do.

Now I would like to have this demo user access all my views but not save to the database when the user saves a form.

Off course there are multiple ways off doing this that I know off. But they all require me to edit multiple pages or views:


  • When saving a form check if it is the demo user, if yes: don't save

  • Remove the save button from my templates when the demo user is logged in



Is there a easier/cleaner solution to do this? How can I set-up my application in a way that a specific user can never save to the database?

The solution I used

marcusshep's idea provided a solution for me. I created the following Views for pages where the form should be loaded but not saved when hitting the save button

class FormViewOPRadio(FormView):
def form_valid(self, form):
# Return 403 for demo user
if self.request.user.email == 'demo@opradio.nl':
raise PermissionDenied
else:
return super(FormViewOPRadio, self).form_valid(form)


class UpdateViewOPRadio(UpdateView):
def form_valid(self, form):
# Return 403 for demo user
if self.request.user.email == 'demo@opradio.nl':
raise PermissionDenied
else:
return super(UpdateViewOPRadio, self).form_valid(form)


Furthermore there are also some pages which should be inaccessible for which I used

from braces.views import UserPassesTestMixin

class UserNotDemoUser(UserPassesTestMixin):
raise_exception = True

def test_func(self, user):
return user.email != 'demo@opradio.nl'

Answer

Off course there are multiple ways of doing this that I know of. But they all require me to edit multiple pages or views:

Well, you won't have to repeat the logic for every template or view if you utilize certain DRY features of Python and Django.

Class Based View Inheritance

class CheckForDemoUser(View):
    def dispatch(self, request, *args, **kwargs):
        # check for demo user
        # handle which ever way you see fit.
        super(CheckForDemoUser, self).dispatch(request, *a, **kw)

class ChildClass(CheckForDemoUser): # notice inheritance here
    def get(request, *args, **kwargs):
        # continue with normal request handling
        # this view will always check for demo user
        # without the need to repeat yourself.

Function Decorators

def check_for_demo_user(func):
   def func_wrapper(request, *args, **kwargs):
       # implement logic to determine what the view should
       # do if the request.user is demo user.
   return func_wrapper


@check_for_demo_user
def my_view(request, *args, **kwargs):
    # automatic checking happening before view gets to this point.

With Inclusion Tags you can isolate the logic of hiding/showing form submit buttons in one place and refer to your custom tag in multiple pages that the demo user would be on.

These are just some of the ways you can implement this logic without having to repeat yourself over and over.

Comments