How can I render a ManyToManyField as checkboxes?
I'm making a game link site, where users can post links to their favorite web game. When people post games they are supposed to check what category the game falls into. I decided to allow many categories for each game since some games can fall into many categories. So the question is, how do I handle this in my view? And how can I show it as Checkboxes, where at least one has to be checked? And how can I show this as checkboxes in the Admin as well?
Here is the code
Models:
class Category(models.Model):
category = models.CharField(max_length=200)
def __unicode__(self):
return self.category
class Game(models.Model):
name = models.CharField(max_length=200)
url = models.CharField(max_length=200)
poster = models.ForeignKey(User, related_name='game_poster_set')
postdate = models.DateTimeField(default=datetime.now)
cats = models.ManyToManyField(Category)
hits = models.IntegerField(default=0)
post = models.BooleanField(default=False)
Views:
def submit(request):
form = GameForm(request.POST or None)
if form.is_valid():
game = form.save(commit=False)
game.poster = request.user
game.save()
开发者_JS百科 next = reverse('gamesite.games.views.favorites')
return HttpResponseRedirect(next)
return render_to_response(
'games/submit.html',
{'form': form},
context_instance = RequestContext(request),)
Forms:
class GameForm(forms.ModelForm):
name = forms.CharField(max_length=15, label='Name')
url = forms.URLField(label='URL', initial='http://')
class Meta:
model = Game
fields = ('name','url')
Thanks!
class GameForm(forms.ModelForm):
name = forms.CharField(max_length=15, label='Name')
url = forms.URLField(label='URL', initial='http://')
cats = forms.ModelMultipleChoiceField(
queryset=Category.objects.all(),
widget=forms.CheckboxSelectMultiple,
required=True)
class Meta:
model = Game
fields = ('name','url','cats')
that should fix your view, but i'm not sure about the admin. still looking... will edit if i find anything.
Here is how I solved it (Edit: and the admin thing)
Forms:
cats = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Category.objects.all())
(It was the queryset part I couldn't find..)
View:
cats = form.cleaned_data['cats']
game.cats = cats
And that's all the code needed to save the data.
Edit: here is a solution for the admin
Models:
from django.contrib import admin
from django.forms import CheckboxSelectMultiple
class MyModelAdmin(admin.ModelAdmin):
formfield_overrides = {
models.ManyToManyField: {'widget': CheckboxSelectMultiple},
}
Admin:
from gamesite.games.models import Game, MyModelAdmin
admin.site.register(Game, MyModelAdmin)
It's kind of quirky in looks, but works! If someone finds a way to make it more "clean" please post!
Cheers!
Found this on from Chase Seibert, Engineering Manager of Dropbox
Source from Chase Seibert
from django.db import models
from django.forms.models import ModelForm
from django.forms.widgets import CheckboxSelectMultiple
class Company(models.Model):
industries = models.ManyToManyField(Industry, blank=True, null=True)
class CompanyForm(ModelForm):
class Meta:
model = Company
fields = ("industries")
def __init__(self, *args, **kwargs):
super(CompanyForm, self).__init__(*args, **kwargs)
self.fields["industries"].widget = CheckboxSelectMultiple()
self.fields["industries"].queryset = Industry.objects.all()
精彩评论