maulik13
maulik13

Reputation: 3760

In Django, how to implement a form to assign multiple users to an item?

I have two models that I need to create a form for.

def Item(models.Model):
    title = models.CharField()
    description = models.TextField()

def ItemUser(models.Model):
    item = models.ForeignKey(Item)
    user = models.ForeignKey(User)

I need to make a form where a user can create a new Item and be able to add/remove multiple ItemUser. Since I am using email address as a user id, I plan to have that entered as input for ItemUser. So the form should render input boxes for taking email addresses and then on the backend I would need to fetch user ids for these email addresses to save into ItemUser table.

How do I implement this form in Django?

EDIT:

Adding another model example to add clarity.

def Blog(models.Model):
    creator = models.ForeignKey(User)
    title = models.CharField()
    description = models.TextField()

def BlogAccessUser(models.Model):
    blog = models.ForeignKey(Blog)
    access_user = models.ForeignKey(User)

Each blog has a list of users that are allowed to access it. So in the form a user will create a blog and also add multiple users to this blog. Something like "Share" feature in Google DOCS where I can add multiple users to my document.

Upvotes: 1

Views: 243

Answers (2)

maulik13
maulik13

Reputation: 3760

The answer to the original question was to use formsets in Django. I ended up using an InlineFormset and writing a custom render method for the form. I also used JS to dynamically add/remove forms.

Upvotes: 0

Glyn Jackson
Glyn Jackson

Reputation: 8354

where a user can create a new item

So this would suggest an Item belongs to one user, one-to-one relationship. So lets start off with this...

def Item(models.Model):
    title = models.CharField()
    description = models.TextField()
    user = models.OneToOneField(User, related_name="item")

be able to add/remove multiple ItemUser

This would suggest a many-to-many relationship so you will need to add this also to item model...

def Item(models.Model):
    title = models.CharField()
    description = models.TextField()
    user = models.OneToOneField(User, related_name="item")
    item_users = models.ManyToManyField(ItemUser, related_name="item")

I need to make a form

So for this you create a model form, which you can filter on email, as you can see email is passed when you create the form init.

    class ItemForm(forms.ModelForm):
        class Meta:
            model = Item

          def __init__(self, email=None, *args, **kwargs):
          super(ItemForm, self).__init__(*args, **kwargs)

        # Representing the many to many related field in Item
        ItemUsers = forms.ModelMultipleChoiceField(queryset=ItemUser.objects.filter(user__email=email))
self.fields['item_users'] = forms.ModelChoiceField(queryset=ItemUsers)

Thats it, in your view just pass the email for filtering, form = itemForm(email=email)

Above was freehand so there could be a few mistakes in their, but it should give you the right idea, hope this helps.

Upvotes: 2

Related Questions