Note that there are some explanatory texts on larger screens.

plurals
  1. POHow Can I Populate Default Form Data with a ManyToMany Field?
    primarykey
    data
    text
    <p>Ok, I've been crawling google and Django documentation for over 2 hours now (as well as the IRC channel on freenode), and haven't been able to figure this one out.</p> <p>Basically, I have a model called <code>Room</code>, which is displayed below:</p> <pre><code>class Room(models.Model): """ A `Partyline` room. Rooms on the `Partyline`s are like mini-chatrooms. Each room has a variable amount of `Caller`s, and usually a moderator of some sort. Each `Partyline` has many rooms, and it is common for `Caller`s to join multiple rooms over the duration of their call. """ LIVE = 0 PRIVATE = 1 ONE_ON_ONE = 2 UNCENSORED = 3 BULLETIN_BOARD = 4 CHILL = 5 PHONE_BOOTH = 6 TYPE_CHOICES = ( ('LR', 'Live Room'), ('PR', 'Private Room'), ('UR', 'Uncensored Room'), ) type = models.CharField('Room Type', max_length=2, choices=TYPE_CHOICES) number = models.IntegerField('Room Number') partyline = models.ForeignKey(Partyline) owner = models.ForeignKey(User, blank=True, null=True) bans = models.ManyToManyField(Caller, blank=True, null=True) def __unicode__(self): return "%s - %s %d" % (self.partyline.name, self.type, self.number) </code></pre> <p>I've also got a forms.py which has the following ModelForm to represent my <code>Room</code> model:</p> <pre><code>from django.forms import ModelForm from partyline_portal.rooms.models import Room class RoomForm(ModelForm): class Meta: model = Room </code></pre> <p>I'm creating a view which allows administrators to edit a given <code>Room</code> object. Here's my view (so far):</p> <pre><code>def edit_room(request, id=None): """ Edit various attributes of a specific `Room`. Room owners do not have access to this page. They cannot edit the attributes of the `Room`(s) that they control. """ room = get_object_or_404(Room, id=id) if not room.is_owner(request.user): return HttpResponseForbidden('Forbidden.') if is_user_type(request.user, ['admin']): form_type = RoomForm elif is_user_type(request.user, ['lm']): form_type = LineManagerEditRoomForm elif is_user_type(request.user, ['lo']): form_type = LineOwnerEditRoomForm if request.method == 'POST': form = form_type(request.POST, instance=room) if form.is_valid(): if 'owner' in form.cleaned_data: room.owner = form.cleaned_data['owner'] room.save() else: defaults = {'type': room.type, 'number': room.number, 'partyline': room.partyline.id} if room.owner: defaults['owner'] = room.owner.id if room.bans: defaults['bans'] = room.bans.all() ### this does not work properly! form = form_type(defaults, instance=room) variables = RequestContext(request, {'form': form, 'room': room}) return render_to_response('portal/rooms/edit.html', variables) </code></pre> <p>Now, this view works fine when I view the page. It shows all of the form attributes, and all of the default values are filled in (when users do a GET)... EXCEPT for the default values for the ManyToMany field 'bans'.</p> <p>Basically, if an admins clicks on a <code>Room</code> object to edit, the page they go to will show all of the <code>Room</code>s default values except for the 'bans'. No matter what I do, I can't find a way to get Django to display the currently 'banned users' for the <code>Room</code> object. Here is the line of code that needs to be changed (from the view):</p> <pre><code>defaults = {'type': room.type, 'number': room.number, 'partyline': room.partyline.id} if room.owner: defaults['owner'] = room.owner.id if room.bans: defaults['bans'] = room.bans.all() ### this does not work properly! </code></pre> <p>There must be some other syntax I have to use to specify the default value for the 'bans' field. I've really been pulling my hair out on this one, and would definitely appreciate some help.</p> <p>Thanks!</p> <p><strong>UPDATE</strong></p> <p>lazerscience actually helped me find the solution in one of his comments. Basically, the way it works is if you pass a list of primary keys. To make it work I had to change:</p> <pre><code>if room.bans: defaults['bans'] = room.bans.all() ### this does not work properly! </code></pre> <p>to</p> <pre><code>if room.bans: defaults['bans'] = [b.pk for b in room.bans.all()] </code></pre> <p>And bam, it instantly started working (when I view the page, it will show a selectable list of <code>Caller</code>s, with the already banned callers already highlighted (selected).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload