Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to store multi-select results in Django model

all:

What is the correct Model fieldtype to use with a CheckboxSelectMultiple widget for static data? I am receiving validation errors and feel I'm missing something simple.

The app is a simple Django 1.6 app in which a Campground object can have multiple eligible_days (e.g. Site #123 may be available on Monday & Tuesday, while Site #456 is available on Weds-Friday).

Because it's static data and I've ready that a ManyToManyField has unnecessary DB overhead, I'm trying to do this with choices defined inside the model, but when I try to save I get the validation error Select a valid choice. [u'5', u'6'] is not one of the available choices. every time.

  • Q1: Do I have to override/subclass a field to support this?
  • Q2: Do I need a custom validation method to support this?
  • Q3: Am I making things unnecessarily hard on myself by avoiding ManyToManyField?

Thank you for your help! /m

models.py

class CampgroundQuery(models.Model):
SUN = 0
MON = 1
TUE = 2
WED = 3
THU = 4
FRI = 5
SAT = 6

DAYS_OF_WEEK_CHOICES = (
    (SUN, 'Sunday'),
    (MON, 'Monday'),
    (TUE, 'Tuesday'),
    (WED, 'Wednesday'),
    (THU, 'Thursday'),
    (FRI, 'Friday'),
    (SAT, 'Saturday'),
)

# loads choices from defined list
eligible_days = models.CharField(max_length=14,choices=DAYS_OF_WEEK_CHOICES,
    blank=False, default='Saturday')
campground_id = models.SmallIntegerField()
stay_length = models.SmallIntegerField()
start_date = models.DateField()
end_date = models.DateField()

admin.py

from django.contrib import admin
from searcher.models import CampgroundQuery
from forms import CampgroundQueryAdminForm

class CampgroundQueryAdmin(admin.ModelAdmin):
    form = CampgroundQueryAdminForm

admin.site.register(CampgroundQuery, CampgroundQueryAdmin)

forms.py

from django import forms
from django.contrib import admin
from searcher.models import CampgroundQuery

class CampgroundQueryAdminForm(forms.ModelForm):
    class Meta:
        model = CampgroundQuery
        widgets = {
            'eligible_days': forms.widgets.CheckboxSelectMultiple
        }
like image 944
mrisher Avatar asked Nov 29 '13 00:11

mrisher


People also ask

How do I save multiple records in Django Unchained?

To create multiple records based on a Django model you can use the built-in bulk_create() method. The advantage of the bulk_create() method is that it creates all entries in a single query, so it's very efficient if you have a list of a dozen or a hundred entries you wish to create.

What is __ str __ In Django model?

The __str__ method just tells Django what to print when it needs to print out an instance of the any model.

What is timestamped model in Django?

TimeStampedModel - An Abstract Base Class model that provides self-managed created and modified fields.


2 Answers

I know this is an old question, but for those who wish to avoid using a ManyToManyField, there is a package to do this, django-multiselectfield, which is quick and easy to implement.

forms.py

from multiselectfield import MultiSelectFormField

class MyForm(forms.ModelForm):
    my_field = MultiSelectFormField(choices=MyModel.MY_CHOICES)

models.py

from multiselectfield import MultiSelectField

class MyModel(models.Model):
    MY_CHOICES = (
        ('a', "A good choice"),
        ...
        ('f', "A bad choice"),
    )
    my_field = MultiSelectField(choices=MY_CHOICES, max_length=11)

And that's it! It stores the keys of MY_CHOICES in a comma-separated string. Easy!

like image 173
TAH Avatar answered Nov 15 '22 03:11

TAH


A ManyToManyField is the correct choice.

In theory you could create a compact representation, like a string field containing representations like "M,W,Th" or an integer that you'll set and interpret as seven binary bits, but that's all an immense amount of trouble to work with. ManyToManyFields are fine.

like image 21
Peter DeGlopper Avatar answered Nov 15 '22 02:11

Peter DeGlopper