How do you make a random selection of a One-to-Many field and store it for all time later?

I’m currently doing the below approach. However, I’m not sure if doing a workcycle.applicants.add will always return in the set up random order (the order users came in with order_by(‘?’)). Does anyone know about this?

class WorkCycle(models.Model):
    job = models.ForeignKey(Job, on_delete=models.CASCADE)
    applicants = models.ManyToManyField(Applicant)

    @classmethod
    def create(cls, job):
        workcycle = cls(job=job)
        tags = [str(tag) for tag in job.tags.all()]
        
        users = User.objects.filter(tags_string__contains=tags[0], role="employee")  # TODO Check
        
        for tag in tags[1:]:
            users = User.objects.filter(tags_string__contains=tag)
            if not users:
                break

        workcycle.save()    # BUGFIX: Save call must go prior to many-to-many field editing (or weird "object needs id" exception)        
        
        for user in users.order_by('?'):    # Return users in random order
            applicant = Applicant(user=user, job=job, created_at=timezone.now(), comment="(TODO)")
            applicant.save()
            workcycle.applicants.add(applicant)
        
        return workcycle
    
    def __str__(self):
        return f'Work cycle for Job ID: {self.job.id}'

If the above approach doesn’t work, then how would I do it? I need both a random order of users (applicants) starting out and also the ability to insert an applicant at a random location (haven’t coded this yet).

I’m not sure I understand exactly what you’re trying to achieve here, but in the absence of an order_by clause in the query, the sequence in which items are returned by a query is indeterminate.

Also keep in mind that adding an entry in a many-to-many relationship affects neither of the two tables involved. A many-to-many relationship is established by the entries in the “join” table created to maintain that relationship.

If you need to ensure some type of sequencing of the entries in that many-to-many, you need to manage it yourself - generally by adding a sequence column to the join table and managing those sequence numbers yourself to establish the desired order.

1 Like

I went ahead and added a rand_order_id field