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:
Form
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
Inline
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
Models
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!
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.
Related
With my reading of many answers to questions similar to mine, all of those answers did not find a solution to my problem.. so I will present them so that I may find a solution that fits my problem:
my View file:
enter image description here
my Template File:
enter image description here
my Admin file:
enter image description here
The Error:
enter image description here
enter image description here
I tried every solution with no hope.
from datetime import datetime
from ckeditor.fields import RichTextField
from multiselectfield import MultiSelectField
from django.db import models
class Car(models.Model):
state_choice = (
('AL', 'Alabama'),
('AK', 'Alaska'),
('AZ', 'Arizona'),
('AR', 'Arkansas'),
('CA', 'California'),
('CO', 'Colorado'),
('CT', 'Connecticut'),
('DE', 'Delaware'),
('DC', 'District Of Columbia'),
('FL', 'Florida'),
('GA', 'Georgia'),
('HI', 'Hawaii'),
('ID', 'Idaho'),
('IL', 'Illinois'),
('IN', 'Indiana'),
('IA', 'Iowa'),
('KS', 'Kansas'),
('KY', 'Kentucky'),
('LA', 'Louisiana'),
('ME', 'Maine'),
('MD', 'Maryland'),
('MA', 'Massachusetts'),
('MI', 'Michigan'),
('MN', 'Minnesota'),
('MS', 'Mississippi'),
('MO', 'Missouri'),
('MT', 'Montana'),
('NE', 'Nebraska'),
('NV', 'Nevada'),
('NH', 'New Hampshire'),
('NJ', 'New Jersey'),
('NM', 'New Mexico'),
('NY', 'New York'),
('NC', 'North Carolina'),
('ND', 'North Dakota'),
('OH', 'Ohio'),
('OK', 'Oklahoma'),
('OR', 'Oregon'),
('PA', 'Pennsylvania'),
('RI', 'Rhode Island'),
('SC', 'South Carolina'),
('SD', 'South Dakota'),
('TN', 'Tennessee'),
('TX', 'Texas'),
('UT', 'Utah'),
('VT', 'Vermont'),
('VA', 'Virginia'),
('WA', 'Washington'),
('WV', 'West Virginia'),
('WI', 'Wisconsin'),
('WY', 'Wyoming'),
)
features_choices = (
('Cruise Control', 'Cruise Control'),
('Audio Interface', 'Audio Interface'),
('Airbags', 'Airbags'),
('Air Conditioning', 'Air Conditioning'),
('Seat Heating', 'Seat Heating'),
('Alarm System', 'Alarm System'),
('ParkAssist', 'ParkAssist'),
('Power Steering', 'Power Steering'),
('Reversing Camera', 'Reversing Camera'),
('Direct Fuel Injection', 'Direct Fuel Injection'),
('Auto Start/Stop', 'Auto Start/Stop'),
('Wind Deflector', 'Wind Deflector'),
('Bluetooth Handset', 'Bluetooth Handset'),
)
door_choices = (
('2', '2'),
('3', '3'),
('4', '4'),
('5', '5'),
('6', '6'),
)
transmission_choice = (
('A', 'Auto_shift'),
('M', 'Manual_shift'),
)
fuel_type_choices = (
('P', 'Petrol'),
('D', 'Diesel'),
('CNG', 'Compressed Natural Gas'),
('Et', 'Ethanol'),
('E', 'Electricity'),
)
year_choice = []
for r in range(2000, (datetime.now().year+1)):
year_choice.append((r, r))
car_title = models.CharField(max_length=255)
city = models.CharField(max_length=100)
state = models.CharField(choices=state_choice, max_length=100)
color = models.CharField(max_length=100)
model = models.CharField(max_length=100)
year = models.IntegerField(('year'), choices=year_choice)
condition = models.CharField(max_length=100)
price = models.IntegerField()
description = RichTextField()
car_photo = models.ImageField(upload_to='photo/%Y%m%d/', blank=True)
car_photo_1 = models.ImageField(upload_to='photo/%Y%m%d/', blank=True)
car_photo_2 = models.ImageField(upload_to='photo/%Y%m%d/', blank=True)
car_photo_3 = models.ImageField(upload_to='photo/%Y%m%d/', blank=True)
car_photo_4 = models.ImageField(upload_to='photo/%Y%m%d/', blank=True)
features = MultiSelectField(choices=features_choices)
body_style = models.CharField(max_length=100)
engine = models.CharField(max_length=100)
transmission = models.CharField(
choices=transmission_choice, max_length=100)
interior = models.CharField(max_length=100)
miles = models.IntegerField()
doors = models.CharField(choices=door_choices, max_length=10)
passengers = models.IntegerField()
vin_no = models.CharField(max_length=100)
milage = models.IntegerField()
fuel_type = models.CharField(choices=fuel_type_choices, max_length=50)
no_of_owners = models.IntegerField()
is_featured = models.BooleanField(default=False)
created_date = models.DateTimeField(default=datetime.now, blank=True)
after trying the proposed solution:
enter image description here
It seems like it's just car 4 that has no image associated with it. Look at the admin. Car 4 exists, but it has no image associated with it, and your template is not checking for that.
{% if car.car_photo_4 %} <!-- just checks if car_photo_4 exists, which it does -->
So try changing it to:
{% if car.car_photo_4.url %}
Note that this is probably also not correct, but I'd need to see your Car model to make it better.
Your issue here is that by checking for {% if car.car_photo_4 %}, you're effectively checking if the attribute exists for this model (which it does, it's just empty). Since we know that car_photo_4 is always defined for the Car model, you should be checking that the url attribute is not empty or null.
You can do this by:
{% if car.car_photo_4.url %}
As a side note, you should use a ManyToManyField instead of statically defining the images as attributes to the Car model as it makes it simply to add more images for the Car model.
I am trying to add classes to my forms but the classes are not being applied. I cannot find what I'm doing wrong. Any help would be greatly appreciated.
I'm hoping to set bootstrap classes, so I'd like , if possible.
class PersonalInformation(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=200, default='')
surname = models.CharField(max_length=200, default='')
dob = models.DateTimeField('Date of birth (mm/dd/yyyy)', null=True, default=now)
preferred_subjects = models.CharField('Are there subjects you would prefer doing?', max_length=200, default='')
class PersonalInformationForm(forms.ModelForm):
OPTIONS = (
("ANI", "Animals"),
("ART", "Art"),
("COM", "Communication"),
)
preferred_subjects = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(
attrs={
'class' : 'not working',
'id' : 'not working'
}
), choices=OPTIONS)
class Meta:
model = PersonalInformation
fields = ['first_name', 'surname', 'dob', 'preferred_subjects']
widgets = {
'dob': DatePickerInput(
options={
"format": "MM/DD/YYYY",
"showClose": False,
"showClear": False,
"showTodayButton": False,
}
),
}
Thank you.
You can try Updating the form field attributes on initiallization.
class PersonalInformationForm(forms.ModelForm):
OPTIONS = (
("ANI", "Animals"),
("ART", "Art"),
("COM", "Communication"),
)
preferred_subjects = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(), choices=OPTIONS)
class Meta:
model = PersonalInformation
fields = ['first_name', 'surname', 'dob', 'preferred_subjects']
widgets = {
'dob': DatePickerInput(
options={
"format": "MM/DD/YYYY",
"showClose": False,
"showClear": False,
"showTodayButton": False,
}
),
}
def __init__(self, request, *args, **kwargs):
super(PersonalInformationForm, self).__init__(*args, **kwargs)
self.fields['preferred_subjects'].widget.attrs.update({'class': 'form-control', 'placeholder': 'First Name'})
EDIT:
preferred_subjects = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(), choices=OPTIONS)
preferred_subjects.widget.attrs.update({'class': 'form-control'})
class Meta:
model = PersonalInformation
fields = ['first_name', 'surname', 'dob', 'preferred_subjects']
widgets = {
'dob': DatePickerInput(
options={
"format": "MM/DD/YYYY",
"showClose": False,
"showClear": False,
"showTodayButton": False,
}
),
}
if this doesnt work, consider using 'SelectMultiple' instead of 'CheckboxSelectMultiple'
forms.MultipleChoiceField(widget=forms.SelectMultiple(), choices=OPTIONS)
I am wokring on a form to save data where from and to days are choice fields in models.py. So I make my form Model in forms.py be choice fields. I've done this far.
models.py
class Create_Class(models.Model):
created_by = models.ForeignKey(
User, on_delete=models.SET_NULL, null=True, default=1)
class_name = models.CharField(max_length=150, null=True)
from_choice = (
('Mon', 'Monday'),
('Tue', 'Tuesday'),
('Wed', 'Wednesday'),
('Thu', 'Thursday'),
('Fri', 'Friday'),
('Sat', 'Saturday'),
('Sun', 'Sunday'),
)
from_days = models.CharField(max_length=10, choices=from_choice)
to_days = models.CharField(max_length=10, choices=from_choice)
from_time = models.TimeField()
to_time = models.TimeField()
created_on = models.DateTimeField(auto_now=True)
forms.py
class Create_Class_Model_Form(forms.ModelForm):
class Meta:
model = Create_Class
exclude = ['created_by', 'created_on']
fields = ['class_name', 'from_days', 'to_days', 'from_time', 'to_time']
from_choice = (
('Mon', 'Monday'),
('Tue', 'Tuesday'),
('Wed', 'Wednesday'),
('Thu', 'Thursday'),
('Fri', 'Friday'),
('Sat', 'Saturday'),
('Sun', 'Sunday'),
)
widgets = {
'class_name': forms.TextInput(attrs={'class': 'form-control'}),
'from_days': forms.ChoiceField(choices=from_choice, widget=forms.ChoiceWidget),
'to_days': forms.ChoiceField(choices=from_choice, widget=forms.Select()),
'from_time': forms.TimeInput(attrs={'class': 'form-control'}),
'to_time': forms.TimeInput(attrs={'class': 'form-control'}),
}
Views.py
def Class_create(request):
form = Create_Class_Model_Form(request.POST or None)
if form.is_valid():
obj = form.save(commit=False)
obj.created_by = request.user.username
obj.save()
print('successful')
messages.success(request, 'Saved Successfully')
c_names = Name_of_classes.objects.values('name')
templatename = 'genius/class_create.html'
context = {'form': form, 'c_names': c_names}
return render(request, templatename, context)
Error
ChoiceField' object has no attribute 'is_hidden'
The error is from forms.py
Your help to solve this error would be appreciated.
ChoiceField is not a widget. Just add it as a field and it should work.
class Create_Class_Model_Form(forms.ModelForm):
from_days = forms.ChoiceField(choices=<the choices>)
to_days = forms.ChoiceField(choices=<the choices>)
class Meta:
....
I have the following model:
class Question(models.Model):
name = RichTextField (
verbose_name = 'Question'
)
QUESTION_TYPE = (
('Multi', 'Multiple Choice (one correct answer)'),
('Check', 'Multiple Answers')
)
question_type = models.CharField(
default = "Multi",
max_length = 7,
verbose_name = "Question Type",
choices = QUESTION_TYPE)
category = models.ForeignKey(
Category,
help_text = 'Category for this Question',
null = True
)
author = models.ForeignKey(
User,
)
quiz = models.ForeignKey (
Quiz,
)
def __unicode__(self):
return u'%s' % (self.name)
I am trying to use a Django form with it so I have this form:
class QuestionForm(forms.ModelForm):
class Meta:
model = Question
fields = ['id','question_type','category','name','author','quiz',]
widgets = {'id': forms.HiddenInput(),
'author': forms.HiddenInput(),
'quiz': forms.HiddenInput(),
'name': forms.TextInput(attrs={'class': 'form-control'}),
'question_type' :forms.Select(attrs={'class': 'form-control'}),
'category' :forms.Select(attrs={'class': 'form-control'}),
}
It works fine except the Category model is associated to a specific Quiz and I only want Categories for the Quiz to which the Question is linked.
class Category(models.Model):
name = models.CharField (
max_length = 30,
verbose_name = "Question Categories",
)
quiz = models.ForeignKey (
Quiz,
verbose_name = 'Quiz',
)
def __unicode__(self):
return u'%s' % (self.name)
I am trying to work out how to limit the Category models presented to the user through the form but I cannot work out how. Help much appreciated.
You could try something like below:
q_info = Question.objects.get(id=question_id)
Q = QuestionForm(instance=q_info)
Q.fields['category'].queryset = Category.objects.filter(condition)
I'have the following ORM Query set, it works properly but now i need it to exclude itself from appearing to a user who already added a row with the same id on the table.
In other words i want the user not to answer the question twice if the user already added an answer to that specific question he will never see the values. here is my query ORM
right_now = datetime.datetime.now() - timedelta(minutes=-10)
partidos = encuesta.objects.filter(fecha__gt=right_now).order_by('fecha')
this ORM Query above shows all the Questions from today untill 10 minutes before the due date.
Now i want show only the questions that a specific user has already answered. as you can see below, i need only to appear those questions he has not answered yet but still being filtered by the date and same order.
Any ideas?
Here is my model.
models.py
class equipo(models.Model):
nombre = models.CharField(max_length=30)
bandera = StdImageField(upload_to='bandera/%Y/%m/%d',
variations={
'large':(53,53, False),
'thumbnail': (70, 26, False)})
GRUPOS = (
('A', 'Grupo A'),
('B', 'Grupo B'),
('C', 'Gropo C'),
('D', 'Gropo D'),
('E', 'Gropo E'),
('F', 'Gropo F'),
('G', 'Gropo G'),
('H', 'Gropo H'),
)
grupo = models.CharField(max_length=1, choices=GRUPOS)
def banderaEquipo(self):
return '<img src="/media/%s">' % (self.bandera.thumbnail)
banderaEquipo.allow_tags = True
def __unicode__(self):
return self.nombre
class encuesta(models.Model):
equipoA = models.ForeignKey(equipo, related_name='equipo_equipoA')
golesEquipoA = models.IntegerField(max_length=2, null=True, blank=True)
equipoB = models.ForeignKey(equipo, related_name='equipo_equipoB')
golesEquipoB = models.IntegerField(max_length=2, null=True, blank=True)
ETAPA = (
('1', 'Primera Etapa'),
('2', 'Octavos De Final'),
('3', 'Cuartos De Final'),
('4', 'Semifinal'),
('5', 'Final'),
('6', '3ra Posicion')
)
etapa = models.CharField(max_length=1, choices=ETAPA)
fecha = models.DateTimeField(auto_now_add=False)
def __unicode__(self):
return "%s Vs. %s" % (unicode(self.equipoA), unicode(self.equipoB))
class respuesta(models.Model):
encuesta = models.ForeignKey(encuesta)
empresa = models.ForeignKey(empresa)
empleado = models.ForeignKey(empleado)
equipoA = models.IntegerField(max_length=1)
equipoB = models.IntegerField(max_length=1)
fecha = models.DateField(auto_now_add=True)
def __unicode__(self):
return "%s" % (unicode(self.encuesta))
Main idea:
Question.objects.exclude(answers__user=user)
In your case (if you add related_name encuestas to respuesta FK field encuesta):
encuesta.objects.exclude(respuesta__empleado=user).filter(fecha__gt=right_now).order_by('fecha')