Select a valid choice. XXXXXXXX is not one of the available choices - python

i want to send sms to selected user form multiple choices by admin side but, I am unable to get the values from the select_users field after the selection is done by the admin. Please help me to solve this.
here's my code
forms.py
class SendSMSForm(forms.ModelForm):
select_users = forms.ModelMultipleChoiceField(queryset=SignUp.objects.all(), widget=forms.CheckboxSelectMultiple)
class Meta:
model = SendSMS
fields = ['sms_subject','sms_text']
widgets = {
'sms_text': forms.Textarea()
}
def __init__(self, *args, **kwargs):
super(SendSMSForm, self).__init__(*args, **kwargs)
self.fields['select_users'].choices = [(str(item.mobile_no), str(item.mobile_no)) for item in SignUp.objects.all()]
admin.py
class SendSMSAdmin(admin.ModelAdmin):
change_form_template = "admin/sms/SmsMarketing/change_form.html"
form = SendSMSForm
list_display = ['sms_subject','sms_text','date1']
list_filter = ('sms_subject',)
def get_form(self, request, obj=None, **kwargs):
if request.method == 'POST':
form = SendSMSForm(request.POST)
if form.is_valid():
subject = form.cleaned_data['sms_subject']
message = form.cleaned_data['sms_text']
***users = form.cleaned_data['select_users']***
print users
obj = SendSMS()
for user in users:
result = obj.sendsms(message, user)
obj_name = User.objects.get(username=user)
if result:
SmsHistory.objects.create(
number=user,
recipient=obj_name.get_full_name(),
sms_subject=subject,
sms_text=message,
sms_type = "Promotional SMS"
)
else:
return SendSMSForm
return SendSMSForm

You could try:
select_users = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple)

Related

How to get current user in forms?

I have a form in my Django project. In this form I can assign person.
This is my form:
class AssignForm(forms.ModelForm):
user = forms.ModelChoiceField(
queryset=UserProfile.objects.filter(is_active=True)
label=_(u'User')
)
class Meta:
model = Customer
fields = ('user',)
I want to add another filter in this form. It is company. I get a list of all users in this form but I want to just listing the users that belongs to current user's company.
So it should be :
queryset=UserProfile.objects.filter(is_active=True, company = current_user.company)
But I cannot get requests from forms. How can I handle it?
You override the constructor of the form with:
class AssignForm(forms.ModelForm):
user = forms.ModelChoiceField(
queryset=UserProfile.objects.filter(is_active=True)
label=_(u'User')
)
def __init__(self, *args, user=None, **kwargs):
super().__init__(*args, **kwargs)
if user is not None:
self.fields['user'].queryset = UserProfile.objects.filter(
is_active=True, company__userprofile=user
)
class Meta:
model = Customer
fields = ('user',)
Then in the view you pass the logged in user:
from django.contrib.auth.decorators import login_required
#login_required
def my_view(request):
if request.method == 'POST':
form = AssignForm(request.POST, request.FILES, user=request.user)
# …
else:
form = AssignForm(user=request.user)
# …
You have to pass the request.user from views.py in order to get it in the form. In your form write this __init__ function and pass the user from your views.py and you can get the user. You can access the user as self.user in your form
class AssignForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.user = kwargs.get('user')
kwargs.pop('user')
In your views.py call the form like below
form = AssignForm(user=request.user)

Django ModelForm not getting instance data

I have a model form that have multiple choice fields. using AJAX to update form choic fields upon changed field.
Model:
class Student(models.Model):
CLASSROOM = 0
GROUPROOM = 1
HOMEROOM = 3
STUDENT_RECORD_TYPES = [
(CLASSROOM,_("Classroom")),
(GROUPROOM,_("Group")),
(HOMEROOM,_("Home Edu")),
]
school = models.ForeignKey(School,on_delete=models.CASCADE,blank=False,related_name='student_records')
grade = models.ForeignKey(Grade,on_delete=models.CASCADE,blank=False,related_name="student_records")
record_type = models.PositiveSmallIntegerField(_("Record Type"),choices=STUDENT_RECORD_TYPES,default=0)
class Meta:
constraints = [
models.UniqueConstraint(
fields=['school','grade', 'record_type'],
name='unique_school_grade_record'
),
]
def __str__(self):
return "Record ID: {}".format(self.pk)
Views.py:
def update_students(request,pk):
updated_table=None
student_record = get_object_or_404(Student,pk=pk)
if request.POST:
form = StudentForm(request.POST or None,instance=student_record)
if form.is_valid():
form.save()
messages.success(request,_("Student record Updated Successfully!"))
#Getting data for view
updated_table = update_students_table(request)
else:
messages.error(request,_("Invalid Input, Please check!"))
else:
form = StudentForm(request.GET or None,instance=student_record)
context = {}
# load form template
context['form'] = form
form_template_path = "components/forms/student_update.html"
html_form = loader.render_to_string(form_template_path, context, request)
context['form'] = html_form
return JsonResponse(context)
Forms.py:
class StudentForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(StudentForm, self).__init__(*args, **kwargs)
for visible in self.visible_fields():
visible.field.widget.attrs['class'] = 'form-control'
self.fields['school'].widget.attrs['class'] += ' select2'
#the issue stands here
#self.data.get('school') returns none even if its exist in form data
if self.data.get('school'):
self.fields['grade'].queryset = Grade.objects.filter(school=self.data.get('school'))
else:
self.fields['grade'].queryset = Grade.objects.none()
class Meta:
model = Student
fields = '__all__'
the strange behavior drives me crazy because when I reselect the school it updates the grade choices normally (with no option selected!), but when I open edit instance form the data is there but grade field have no options in it!

Customizing django form based on currently logged in user

This is a part of my forms.py
class SubjectForm(forms.ModelForm):
title=forms.CharField(label='',widget=forms.TextInput(attrs={'maxlength':150,
'placeholder':'Write here. . .'}))
body=forms.CharField(label='', widget=forms.Textarea(attrs={'placeholder':'Extend here. . .'}))
board=forms.ModelChoiceField(label='',queryset=Board.objects.all(), empty_label='Select Board')
class Meta:
model = Subject
fields = ('title','body','board')
Right now it's rendering all Board objects in board form field but I want to render only those boards in which the user has subscribed. How can I get user in form and manipulate it?
forms.py:
class SubjectForm(forms.ModelForm):
title=forms.CharField(label='',widget=forms.TextInput(attrs={'maxlength':150,
'placeholder':'Write here. . .'}))
body=forms.CharField(label='', widget=forms.Textarea(attrs={'placeholder':'Extend here. . .'}))
board=forms.ModelChoiceField(label='',queryset=Board.objects.all(), empty_label='Select Board')
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super(SubjectForm, self).__init__(*args, **kwargs)
if user is not None:
self.fields['board'].queryset = Board.objects.filter(user=user)
class Meta:
model = Subject
fields = ('title','body','board')
views.py:
demo with CreateView:
class SubjectCreateView(CreateView):
form_class = SubjectForm
template_name = 'subject/create.html'
success_url = '/'
def get_form_kwargs(self):
kwargs = super(SubjectCreateView, self).get_form_kwargs()
if self.request.method == 'GET':
kwargs.update({
'user': self.request.user,
})
return kwargs
or
form = SubjectForm(**{'user': request.user})

form.is_valid() is false why?

I want to store a POST request to a database, so I a had model form MessageForm and called it from views to validate the data and save it.
models.py
class phoneNumber(models.Model):
address = models.CharField(max_length=15)
def __str__(self):
return self.address
class Message(models.Model):
to = models.ForeignKey(phoneNumber, null=True)
sentfrom = models.CharField(max_length=15, null=True)
content = models.TextField(null=True)
def __str__(self):
return '%s' % (self.content)
forms.py
class MessageForm(forms.ModelForm):
class Meta:
model = Message
fields = '__all__'
def __init__(self, *args, **kwargs):
to = kwargs.pop('to', '')
super(MessageForm, self).__init__(*args, **kwargs)
self.fields['to']=forms.ModelChoiceField(queryset=phoneNumber.objects.filter(address=to))
views.py
#csrf_exempt
def incoming(request):
if request.method == "POST":
form = MessageForm(request.POST)
if form.is_valid():
twiml = '<Response><Message>Yes</Message></Response>'
else:
twiml = '<Response><Message>No</Message></Response>'
else:
twiml = '<Response><Message></Message></Response>'
return HttpResponse(twiml, content_type='text/xml')
Nothing is saved and I get No response when I test it.
You can access your errors in views.py
#csrf_exempt
def incoming(request):
if request.method == "POST":
form = MessageForm(request.POST)
if form.is_valid():
twiml = '<Response><Message>Yes</Message></Response>'
else:
print(form.errors)
print(form.non_field_errors)
twiml = '<Response><Message>No</Message></Response>'
else:
twiml = '<Response><Message></Message></Response>'
return HttpResponse(twiml, content_type='text/xml')
Have you tried:
def __init__(self, *args, **kwargs):
to = kwargs.pop('to', '')
super(MessageForm, self).__init__(*args, **kwargs)
self.fields['to'].queryset = phoneNumber.objects.filter(address=to)
Also I'm not sure if you want to pass anything to the form in views method, because right now your to in form is empty string, so your queryset is querying on phoneNumber.objects.filter(address=''), which may or may not be what you want.
Edit:
The reason that to is empty string because kwargs.pop('to', '') means "pop argument to out from kwargs, if to is not there the default is ''". In your views you do:
form = MessageForm(request.POST)
but you didn't feed the constructor with any to argument, so kwargs.pop('to', '') would get '' as default value. You might need something like:
form = MessageForm(request.POST, to="white house")

Django, change username form

I'm trying to create a modelform to allow users to change their username. I'm trying to do this using FormView instead of UpdateView because I want to include other forms (user management functionality) in this view eventually.
Relevant forms.py:
class FormHorizontalModelForm(forms.ModelForm)
def __init__(self, *args, **kwargs):
super(FormHorizontalModelForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_class = 'form-horizontal'
class PlayerRenameForm(FormHorizontalModelForm):
def __init__(self, user, *args, **kwargs):
super(PlayerRenameForm, self).__init__(*args, **kwargs)
self.helper.add_input(Submit('change_username', 'Change Username'))
class Meta:
model = User
fields = ('username',)
def save(self):
pass # I figured this might be saving the object since this is inherited off ModelForm
def form_valid(self, form):
self.change_username(new_username = self.cleaned_data['username'])
# self.send_email(new_username = self.cleaned_data['username'])
def change_username(self, new_username):
player = Player.objects.get(user = self.instance)
self.instance.username = new_username
self.instance.save()
player.changed_username = True
player.save()
views.py
class AccountView(UserAuthenticationMixin, FormView):
template_name = 'game/profile.html'
success_url = '/accounts/'
form_class = PlayerRenameForm
form_class_two = CrispyPasswordSetForm
form_class_three = CrispyPasswordChangeForm
def get_context_data(self, **kwargs):
context = super(AccountView, self).get_context_data(**kwargs)
if 'form' not in context:
context['form'] = self.form_class(user = self.request.user, data = (self.request.POST or None))
if 'password_set_form' not in context:
context['password_set_form'] = self.form_class_two(user = self.request.user, data = (self.request.POST or None))
if 'password_change_form' not in context:
context['password_change_form'] = self.form_class_three(user = self.request.user, data = (self.request.POST or None))
return context
def form_invalid(self, **kwargs):
return self.render_to_response(self.get_context_data(**kwargs))
def get_form(self, form_class):
return form_class(user = self.request.user, **self.get_form_kwargs())
def post(self, request, *args, **kwargs):
if 'change_username' in request.POST:
form = self.form_class(user = request.user, instance = request.user, data = self.request.POST)
form_name = 'form'
elif 'set_password' in request.POST:
form = self.form_class_two(user = request.user, data = self.request.POST)
form_name = 'password_set_form'
elif 'change_password' in request.POST:
form = self.form_class_three(user = request.user, data = self.request.POST)
form_name = 'password_change_form'
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(**{form_name: form})
The form returns valid, and returns to success_url. I know for a fact that it is passing into the correct part of the post function since I have stripped away the other parts to ensure that was working.

Categories