Reputation: 167
I'm trying to change the default ManyToManyField
widget into a TextInput
and make it readonly. At the same time I'm trying to display the value(s) that the ManyToManyField
used to have within the TextInput, but I can't seem to manage...these are my models:
class ParticipantInlineForm(forms.ModelForm):
class Meta:
model = Participant
widgets = {
'persons': forms.TextInput
}
def __init__(self, *args, **kwargs):
super(ParticipantInlineForm, self).__init__(*args,**kwargs)
instance = kwargs.get('instance')
string = ''
if instance:
for person in instance.persons.all():
string = string + str(person)
self.fields['persons'].initial = string
class SimpleParticipantInline(admin.TabularInline):
model = Participant
extra = 0
fields = ( 'persons',)
form = ParticipantInlineForm
def has_delete_permission(self, request, obj=None):
return False
def has_add_permission(self, request, obj=None):
return False
class Person(models.Model):
name = models.CharField(max_length=25, default='', verbose_name='Nombre')
lastname = models.CharField(max_length=25, default='', verbose_name='Apellido')
phone = models.CharField(max_length=30, default='', verbose_name='Telefono')
email = models.CharField(max_length=30, default='', verbose_name='Email')
def __str__(self):
return self.name + ' ' + self.lastname
class Meta:
verbose_name = "Persona"
verbose_name_plural = "Personas"
class Participant(models.Model):
persons = models.ManyToManyField(Person)
tournament = models.ForeignKey(Tournament, default='', verbose_name='Torneo')
TEAM_NUMBER_CHOICES = (
('1', 'Equipo 1'),
('2', 'Equipo 2'),
('3', 'Equipo 3'),
('4', 'Equipo 4'),
('5', 'Equipo 5'),
('6', 'Equipo 6'),
('7', 'Equipo 7'),
('8', 'Equipo 8'),
('9', 'Equipo 9'),
)
team_number = models.CharField(max_length=2, verbose_name='Numero de Equipo', choices=TEAM_NUMBER_CHOICES, default='', blank=True)
TEAM_FORMAT_CHOICES = (
('Singles 1', 'Singles 1'),
('Doubles 1', 'Doubles 1'),
('Singles 2', 'Singles 2'),
('Doubles 2', 'Doubles 2'),
('Singles 3', 'Singles 3'),
('Doubles 3', 'Doubles 3'),
('Singles 4', 'Singles 4'),
('Doubles 4', 'Doubles 4'),
('Singles 5', 'Singles 5'),
('Doubles 5', 'Doubles 5'),
('Singles 6', 'Singles 6'),
('Doubles 6', 'Doubles 6'),
)
team_format = models.CharField(max_length=9, verbose_name='Formato de Equipo', choices=TEAM_FORMAT_CHOICES, default='', blank=True)
def __str__(self):
string = ''
if self.team_number and self.team_format:
string = 'Equipo ' + self.team_number + ' ' + self.team_format
else:
for person in self.persons.all():
string = string + person.__str__() + ' '
return string
class Meta:
verbose_name = "Participante"
verbose_name_plural = "Participantes"
I changed the widget using this code, but the values are wrong. It's showing integers like 1L, 2L, 3L. I think they might be the id's...
I have also tried redefining the widget, but old ManyToManyField objects won't get there and I can't set the initial values, any help?
I just want to show the string representation of each object in the ManyToManyField as a readonly field within the Inline.
Thanks in advance!
Upvotes: 0
Views: 2275
Reputation: 349
I know the question is 2 years old but trying to answer for others who are looking for something similar.
You can use a widget similar to ManyToManyField, SelectMultiple but just mark it as readonly and disabled. Marking these as disabled or readonly within __init__
in forms may not work. It should be done as part of Meta widgets sections.
class ParticipantInlineForm(forms.ModelForm):
class Meta:
model = Participant
widgets = {
'persons': forms.SelectMultiple(attrs={'readonly': 'True', 'disabled': 'True'})
}
Make sure __str__
has been implemented to a meaningful text in Persons class
Since it is disabled and marked as readonly, the value cannot be changed but it displays proper string values.
Upvotes: 1