oTree Forum >

Using ExtraModel with multiple apps

#1 by aseyq

Hi all,

I have an ExtraModel that I need to access in multiple apps. I am able to do that since ExtraModels are accessible. But my current implementation seems a little too hacky. I wondered if there is a better way to deal with that.

So, the problems I encountered:

- P1: ExtraModel is defined on a specific app.
- P2: ExtraModel needs to be linked to a specific model (Player, Group, Subsession) but I wasn't able to link it to a session-wide model (Error: Session/Participant is not defined). Thus, it is not possible to make calls like MyExtraModels.filter(code="abc", session=MySession) or MyExtraModels.filter(code="abc", participant=player.participant).

My workarounds:
P1: I was able to import the model (and relevant functions) from another app. For instance:

`from my_other_app import MyExtraModel, my_function1, my_function2`.

This works fine, but I am not sure it might create any future issues (like overwritten data or something).

P2: I created a function to first get all instances of a model and filters them out. This is probably too inefficient, and I can see it might create problems over time.

def filter_items_by_code(item_code=None):
    all_items = MyExtraModel.filter()
    filtered_items = [i for i in all_items if i.code == item_code]
    return filtered_chains

Okay, all works fine in this form, but am I missing something? Is there an easier way to deal with it?

#2 by Chris_oTree

ExtraModel is currently designed for use within an individual subsession, which is why it has those restrictions. I might extend it for use between apps/sessions/etc, but first I want to understand the use cases so I can come up with the right design. Can you tell me more about your use case? (what the MyExtraModel represents)

#3 by aseyq

I am currently using it to create a "transmission chain": participants interact with each other one after the other. So typically one participant enter, get assigned to a "chain", possibly get some information from the previous person and once finished the chain is ready to accept another participants. So it is like a group with an order: P1 --> P2 --> P3 --> P4

My model is something like this:

class ChainModel(ExtraModel):
    subsession = models.Link(Subsession)
    chain_code = models.StringField() # A code to identify the chain. eg. ABCD
    available = models.BooleanField() # Whether the chain is ready to get the next person
    full = models.BooleanField(initial=False) # chain is full 
    complete = models.BooleanField(initial=False) # chain is completed
    
    p1 = models.Link(Player) 
    id1 = models.IntegerField()
    participant1 = models.StringField()
    finished1 = models.booleanField() # participant is finished
    information1 = models.LongStringField()
    # (I use a loop to generate one for other players in the "chain".

Then I have a bunch of functions like, get_my_chain, create_new_chain, add_player_to_chain, complete_current_player, drop_me_from_chain, get_status_of the chain etc. It also helped me to build a nice dashboard as an admin report. Here is my implementation: https://github.com/aseyq/chaining/tree/main

As it is very much like a group model, and I can probably use it and id_in_group can act like a participant's position/generation. But having this custom ExtaModel is flexible in the sense that I can build it on the fly at any point at a player level (as opposed to group/session level). I can assign a person to an existing group, remove a person who is not finished. 

I can possibly stay in a single app somehow, but having access to the chain in multiple apps makes it much easier and modular. Another reason is that I would like to turn it into an app or a package so others can re-use the same framework, which is very common in some fields.

Of course, for oTree, I have no idea if it makes sense to extend the ExtraModel to multiple apps in terms of cost/benefit. (And for my specific case I used the workarounds I mentioned, so it works alright) But I would think no matter what the use case is, having that flexibility would simplify lots of participant/session var implemenations with complex information. (Like having treatment/session level custom tables in z-Tree). The necessary structure seems to be already there and accessible across the apps.

#4 by Chris_oTree

Thank you for the description. I’ll look at extending ExtraModel to the use case you describe.

#5 by aseyq

Thank you so much, Chris. I am at your service if you need any feedback or if something I can help with comes up.

Write a reply

Set forum username