How to create different paths for users to take through the pages in my site?

I have a website where users are directed to go through a sequence of pages to perform a sequence of work tasks (transcribe a paragraph, answer a survey, interact with another user, etc). For short, let’s call these tasks A, B, C, etc. I’m using Django, and each task is currently implemented as a view function (or method), e.g. def A(request). Currently, each view function has the next step hardcoded in an HTTP redirect, e.g. HttpResponseRedirect(reverse(B)).

My challenge is that I will soon have a requirement to create various permutations of the sequence of tasks. Sometimes I will want users to do A, B, C; for others, B, C, D; for others, A, B, D, F. How can I architect this so that I can define these permutations elegantly and concisely in my code? Intuitively, I feel like I need to genericize the HTTP redirect calls with a variable, like: HttpResponseRedirect(reverse(next_view_function)), but I struggle to figure out where next_view_function should be defined, and how the definition of the sequence (e.g. A, B, D) should be persisted across requests.

Can anyone lead me down the right path with a suggestion or idea? I’m happy to provide more details.

Edit in response to Bart’s questions:

  • The order of tasks is predetermined. Once we have defined it, we send the users a URL that takes them to the first page. They should then be routed through the tasks. One group of users might get a URL that takes them through steps A,B,C, while another group of users gets a URL that takes them through steps A,B,D. We decide in advance which users should get which URL.
  • Since the order is predetermined, the next step does not depend on the results of the current task. The only requirement is for them to complete the task (we of course validate the POST data they submit as a precondition to the HTTP redirect).

Edit 2, my solution so far:

A central concept in my code architecture is that of a “Treatment” (defined in my models.py). A Treatment is a specification of the experience a user has when they use my site, such as what UI is presented to them. I split my users into groups and assign each group to a different treatment by emailing them a URL that contains the PK of their treatment.

(There are also different subclasses of Treatment, since some Treatments are totally different from others. SoccerTreatment and HockeyTreatment have little in common, so it makes sense to subclass them.)

So, the class definition for a Treatment seems like the sensible place to store the sequence of views as a Python list, as follows:

# in soccer/models.py
class SoccerTreatment(BaseTreatment):

    world_cup = models.BooleanField()
    ....

    def views(self, request):
        seq = [soccer.views.ViewClassA]
        if self.world_cup:
            seq.append(soccer.views.ViewClassWorldCup)

        return seq

# in shared/models.py
class BaseTreatment(models.Model):    
    def next_view(self, request):
        seq = self.views() # views() method implemented by descendant classes
        if request.session.get('current_view_index'):
            request.session['current_view_index'] += 1
        else:
            request.session['current_view_index'] = 0
        # [handle boundary cases, code snipped...]
        # ...
        return seq[request.session['current_view_index']]


    # ...

# in views.py, at the end of a view function
# ...
HttpResponseRedirect(reverse(user.treatment.next_view()))

However, the design above wouldn’t work, since then models.py would have to import views.py, creating a circular import. So the list elements would have to be strings (either URLs, or a the name of the view class as a string), which could be brittle since renaming my classes or URLs won’t automatically rename these strings.

Maybe I am being too picky, but I wonder if there is a better design.

I’ve only skimmed the requirements, but I’d be thinking something simple like this:

  1. Give each task a letter.
  2. Generate a task sequence string (eg, EBDFA) for a user.
  3. Look at the first letter to decide what task to do next.
  4. Carry out that task.
  5. Strip the first letter off, pass the rest in the URL.
  6. Go to step 3.

Keep it simple. Don’t create models you don’t need, don’t store local state you don’t need.

2

You’ll have to group your users according to the flow assignments. For each usergroup you have sequence of pages. The data model will then be something like

User     -->   UserGroup  <--  Sequences
+id            +id             +user_group_id
+name                          +current_step
+user_group_id                 +next_step

On each single page you know the user’s id and the current step, so you can easily retrieve the next step for the current situation.

There are a few questions that will affect the design here:

  1. Do you already have information that will determine the set/order of tasks, or will the order effectively be random? In the latter case, you could generate the task list when you create a new session and pass it along in the session data, along with an indicator where in the list the user is.
  2. If you already have information on the set/order of tasks, in how far does this information consist of the answers/result of the current task? If there is a strong influence of the current task in selecting the next, you might be better off with a next_view_function per task. Otherwise, you might have one is a base class that all task controllers inherit from.

Update

In response to the update: You can either encode the sequence in the URL you give out (base64 encoded if you don’t want it to be too obvious), or you can store the information in the session, like with the random order, except that the initial URL drives the sequence generation, instead it being random.

2

I came across a situation like this in an Application I helped create.

I called it the User Sanity Test, because I was testing the User model and the possible states it could be in with regards to its relations to other models.

Things I would test were, Had they set an email address, Did they have valid billing details, have they created their first Thing(tm), etc.

I approached this by creating a Middleware that performed these tests on authenticated users, which took the UserSanityTest class and feeds in the current User.

If a test fails, then it returns an url that the middleware will redirect the user to.

The Sanity check is in effect on all urls except those in the SanityCheck.

If the user is visiting a SanityCheck Url that they’ve already satisfied then it either sends them to the users dashboard or checks for other SanityChecks and processes them.

Normal URLS described in your UrlConf can only be visited when all SanityChecks are completed.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật