12π
Can a Car
have multiple color
s? In that case color
ought to be a many to many relationship rather than a CharField
. If on the other hand you want to do something like Unix permissions (i.e. Red + Blue, Red + Blue + Green etc.) then assign numeric values of to each of them and make color
an integer field.
Update
(After reading comment) You can use a custom form to edit your model in Admin instead of the default ModelForm
. This custom form can use a multiple choice widget that lets users select multiple colors. You can then override the clean()
method of the form to return a suitably concatenated value (βRBβ etc.).
Update 2
Here is some code:
First, remove the choices from the model field. Also increase its maximum size to 2. We donβt want choices here β if we do, then weβll have to add a choice for each combination of colors.
class Car(models.Model):
...
color= models.CharField(max_length=2)
Second add a custom ModelForm
to use in admin app. This form will override color and instead declare it as a multiple choice field. We do need choices here.
COLORS= (
('R', 'Red'),
('B', 'Yellow'),
('G', 'White'),
)
class CarAdminForm(ModelForm):
color = forms.MultipleChoiceField(choices = COLORS)
class Meta:
model = Car
def clean_color(self):
color = self.cleaned_data['color']
if not color:
raise forms.ValidationError("...")
if len(color) > 2:
raise forms.ValidationError("...")
color = ''.join(color)
return color
Note that I have added only a couple of validations. You may want more and/or customize the validations.
Finally, register this form with admin. Inside your admin.py
:
class CarAdmin(admin.ModelAdmin):
form = CarAdminForm
admin.site.register(Car, CarAdmin)
7π
Iβve constructed a complete working example with meaningful models. It works perfect. Iβve tested it on Python 3.4.x and Django 1.8.4.
At first I run admin panel and create records for each option in Thema model
models.py
from django.db import models
class Author(models.Model):
fname = models.CharField(max_length=50)
lname = models.CharField(max_length=80)
def __str__(self):
return "{0} {1}".format(self.fname, self.lname)
class Thema(models.Model):
THEME_CHOICES = (
('tech', 'Technical'),
('novel', 'Novel'),
('physco', 'Phsycological'),
)
name = models.CharField(max_length=20,choices=THEME_CHOICES, unique=True)
def __str__(self):
return self.name
class Book(models.Model):
name = models.CharField(max_length=50)
author = models.ForeignKey(Author)
themes = models.ManyToManyField(Thema)
def __str__(self):
return "{0} by {1}".format(self.name,self.author)
forms.py
from django import forms
from .models import *
class BookForm(forms.ModelForm):
themes = forms.ModelMultipleChoiceField(queryset=Thema.objects, widget=forms.CheckboxSelectMultiple(), required=False)
admin.py
from django.contrib import admin
from .models import *
from .forms import *
@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
pass
@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
form = BookForm
@admin.register(Thema)
class ThemaAdmin(admin.ModelAdmin):
pass
- Django + celery β How do I set up a crontab schedule for celery in my django app?
- System date formatting not using django locale
1π
Use a separate table with colors (Red, Blue, Green), and, as you said, add a many to many relationship ?
Choice type is not multiple choice, only a string with added UI and checkings.
Or, generate procedurally your choices with itertools.combinations, example:
choices = zip(
[''.join(x) for x in itertools.combinations(['','B','R','G'],2)],
[' '.join(x) for x in itertools.combinations(['','Blue','Red','Green'],2)],
)
# now choices = [(' Blue', 'B'), (' Red', 'R'), (' Green', 'G'), ('Blue Red', 'BR'), ('Blue Green', 'BG'), ('Red Green', 'RG')]
- Django: generate download link
- Django Test Client post() returns 302 despite error on view's post()
- NameError:Admin not found in django
1π
For colors tuple, if you use integers instead of chars, you may use commaseparatedintegerfield for your model.
But Do not forget, commaseparatedintegerfield is a database level structure,so your DBMS must support it.
- Django message template tag checking
- How can I make SSE with Python (Django)?
- Logout Django Rest Framework JWT
- Django β filtering by "certain value or None"
0π
The easiest way I found (just I use eval() to convert string gotten from input to tuple to read again for form instance or other place)
This trick works very well
#model.py
class ClassName(models.Model):
field_name = models.CharField(max_length=100)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.field_name:
self.field_name= eval(self.field_name)
#form.py
CHOICES = [('pi', 'PI'), ('ci', 'CI')]
class ClassNameForm(forms.ModelForm):
field_name = forms.MultipleChoiceField(choices=CHOICES)
class Meta:
model = ClassName
fields = ['field_name',]
#view.py
def viewfunction(request, pk):
ins = ClassName.objects.get(pk=pk)
form = ClassNameForm(instance=ins)
if request.method == 'POST':
form = form (request.POST, instance=ins)
if form.is_valid():
form.save()
...
0π
Django models come with JSONField() which you could use to serialize the list of integer values and later deserialize it into a list. List of integers are your colors.
https://docs.djangoproject.com/en/4.0/ref/models/fields/#django.db.models.JSONField