I have a problem with a foreing key field that I initialize with a queryset, the form is displayed but at the time of sending data the error 'in to_python raise ValidationError (self.error_messages [' invalid_choice '], code =' invalid_choice ')' appears' .
I know there is a way to invalidate the 'to_python' method but I still can not get it to work. I would appreciate any help.
My view:
class PlanesCreate(generic.CreateView):
model= Plan_Estudios
template_name= 'ControlEscolar/Administracion/planes/planes_form.html'
form_class= PlanForm
success_url = reverse_lazy('ControlEscolar:planes_filtro')
def get_form_kwargs(self):
kwargs = super(PlanesCreate, self).get_form_kwargs()
kwargs.update({'programa': self.request.session['programa']})
return kwargs
My form:
class PlanForm(forms.ModelForm):
class Meta:
model = Plan_Estudios
fields = "__all__"
widgets = {
'nombreplan': forms.TextInput(attrs={'class':'form-control'}),
'programa': forms.Select(attrs={'class':'form-control'}),
}
def __init__(self, *args, **kwargs):
p=kwargs.pop('programa', None)
super(PlanForm, self).__init__(*args, **kwargs)
query=Programa_Academico.objects.filter(pk=p)
self.fields['programa'].queryset=query #Inicialize field with query
My model:
class Plan_Estudios(models.Model):
nombreplan= models.CharField(max_length=30)
programa= models.ForeignKey(Programa_Academico, on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.nombreplan
class Programa_Academico(models.Model):
nombreP= models.CharField(max_length=50)
siglas= models.CharField(max_length=10)
def __str__(self):
return self.siglas
Error:
File "C:\Users\Envs\py1\lib\site-packages\django\forms\forms.py" in is_valid
185. return self.is_bound and not self.errors
File "C:\Users\Envs\py1\lib\site-packages\django\forms\forms.py" in errors
180. self.full_clean()
File "C:\Users\Envs\py1\lib\site-packages\django\forms\forms.py" in full_clean
381. self._clean_fields()
File "C:\Users\Envs\py1\lib\site-packages\django\forms\forms.py" in _clean_fields
399. value = field.clean(value)
File "C:\Users\Envs\py1\lib\site-packages\django\forms\fields.py" in clean
147. value = self.to_python(value)
File "C:\Users\Envs\py1\lib\site-packages\django\forms\models.py" in to_python
1252.
raise ValidationError(self.error_messages['invalid_choice'],
code='invalid_choice')
Exception Type: KeyError at /ControlEscolar/planes/crear
Exception Value: 'invalid_choice'
Related
I'm using InlineFormSetView from extra_views to create a custom inlineform.
On form save I need to make some changes that's relevant to the request user. So the request user is required in the form. From what I found, I came up with this solution but it seems that get_formset_kwargs may be used elsewhere. Causing an exception to occur. I'm not quite sure what is the cause. May be there is another solution to adding request user to an inline form.
View:
class MyModelSetsView(InlineFormSetView):
model = MyModel
inline_model = MySubModel
form_class = MySubModelSetForm
template_name = "update_sets.html"
success_message = "Updated successfully."
permission_required = []
factory_kwargs = {
'extra': 1,
}
def get_success_url(self):
return self.object.get_absolute_url()
def get_formset_kwargs(self):
kwargs = super(MyModelSetsView, self).get_formset_kwargs()
kwargs.update({'user': self.request.user})
return kwargs
Form:
class MySubModelSetForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(PeakPeriodSetForm, self).__init__(*args, **kwargs)
Exception:
File "..\venv\lib\site-packages\extra_views\formsets.py", line 268, in get
formset = self.construct_formset()
File "...venv\lib\site-packages\extra_views\formsets.py", line 36, in construct_formset
return formset_class(**self.get_formset_kwargs())
File "...\venv\lib\site-packages\django\forms\models.py", line 897, in __init__
super().__init__(data, files, prefix=prefix, queryset=qs, **kwargs)
File "...\venv\lib\site-packages\django\forms\models.py", line 569, in __init__
super().__init__(**{'data': data, 'files': files, 'auto_id': auto_id, 'prefix': prefix, **kwargs})
TypeError: __init__() got an unexpected keyword argument 'user'
Solution I found was handling the form in the view using formset_valid method.
def formset_valid(self, formset):
for form in formset:
data= form.cleaned_data
print(data)
return super().formset_valid(formset)
Calling save() on a serializer is returning below error:
Original exception was:
Traceback (most recent call last):
File "C:\Users\aditya\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\rest_framework\serializers.py", line 940, in create
instance = ModelClass.objects.create(**validated_data)
File "C:\Users\aditya\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\aditya\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\query.py", line 417, in create
obj.save(force_insert=True, using=self.db)
TypeError: save() got an unexpected keyword argument 'force_insert'
views.py
def post(self,request):
if request.method=='POST':
serializer = invoiceSerializers(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
model.py
class invoice(models.Model):
customer = models.CharField(max_length=256, blank=False)
date = models.DateField(default=now)
invoice_number = models.IntegerField(editable=False,default=1)
total_quantity = models.DecimalField(max_digits=10, decimal_places=2)
total_amount = models.DecimalField(max_digits=10, decimal_places=2)
total_tax = models.DecimalField(max_digits=10, decimal_places=2)
def save(self):
if self._state.adding:
last_invoice=invoice.objects.all().aggregate(largest=models.Max('invoice_number'))['largest']
if last_invoice is not None:
self.invoice_number=last_invoice+1
super(invoice,self).save()
I am not able to understand why this is happening and how to fix this. Any help is appreciated.
The save() method of Model accepts few keyword arguments such as force_insert,using etc. But, you are not accepting those arguments in your override methods.
So change your save() method as
class invoice(models.Model):
.....
.....
.....
# your code
def save(self, *args, **kwargs):
.....
.....
.....
# your code
super(invoice, self).save(*args, **kwargs)
I have an issue that makes me crazy
I have model
class Property1(CommonInfo):
unit = models.ForeignKey(Unit)
is_true = models.BooleanField(default=False)
propertytype = models.ForeignKey(Propertytype, related_name='propertytype')
date = models.DateTimeField(null=True, blank=True)
followup_date = models.DateTimeField(null=True, blank=True)
quantity = models.PositiveSmallIntegerField()
def __str__(self):
return self.propertytype
def clean(self):
model = self.__class__
if (self.unit) and model.objects.filter(unit=self.unit, propertytype=self.propertytype ).exclude(id=self.id).count() == 1:
raise ValidationError('Same property cant be assigned more then ones')
for this model I have form
class Property1Form(forms.ModelForm):
class Meta:
model = Property1
fields = ['unit','propertytype','is_true','date','followup_date','quantity','description']
def __init__(self, *args, **kwargs):
super(Property1Form, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if instance:
self.fields['unit'].required = False
self.fields['unit'].widget.attrs['disabled'] = 'disabled'
And I have a view
def property_new(request,pk,uri):
unit = get_object_or_404(Unit, pk=pk)
title = 'property'
uri = _get_redirect_url(request, uri)
if request.method == "POST":
form = Property1Form(request.POST)
form.unit = unit
if form.is_valid():
properties = form.save(commit=False)
properties.unit = unit
properties.save()
messages.add_message(request, messages.SUCCESS, str(properties.unit) + "-SUCCESS Object created sucssefully")
return redirect(uri)
else:
form = Property1Form(initial={'unit': unit})
return render(request, 'object_edit.html', {'form': form, 'title':title, 'extend': EXTEND})
However, after creating new property I always get
RelatedObjectDoesNotExist at *** Property1 has no unit.
Error triggered during execution of
if form.is_valid():
What is the problem?
UPDATE:
Traceback:
File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\core\handlers\base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Boris\dev\rentout\rentout\unit\views.py" in property_new
390. if form.is_valid():
File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\forms\forms.py" in is_valid
184. return self.is_bound and not self.errors
File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\forms\forms.py" in errors
176. self.full_clean()
File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\forms\forms.py" in full_clean
394. self._post_clean()
File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\forms\models.py" in _post_clean
430. self.instance.full_clean(exclude=exclude, validate_unique=False)
File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\models\base.py" in full_clean
1132. self.clean()
File "C:\Users\Boris\dev\rentout\rentout\unit\models.py" in clean
117. if (self.unit) and model.objects.filter(unit=self.unit, propertytype=self.propertytype ).exclude(id=self.id).count() == 1:
File "C:\Users\Boris\dev\rentout\virtrentout\lib\site-packages\django\db\models\fields\related.py" in __get__
608. "%s has no %s." % (self.field.model.__name__, self.field.name)
Exception Type: RelatedObjectDoesNotExist at /unit/property/new/6/http://127.0.0.1:8000/unit/property_details/6/
Exception Value: Property1 has no unit.
Setting required=False and disabling the widget is not ideal. Disabling the widget means that your browser will not submit any values for that field. Since you have required=False, this means that the form will set the foreign key to None. However, this is incompatible with the model's foreign key, which has null=False by default.
I'm not familiar enough with the internals to precisely explain the exception, but the basic problem is that Django is trying to fetch the related unit from the database, after the form has set the foreign key to None.
One work around is to check self.unit_id rather than self.unit. This prevents the database lookup, so you don't get the exception.
However, this seems a bit dirty to me. If you don't want the user to edit the unit field, I would remove it from the form completely. Check self.instance.pk to determine whether or not the instance is in the database already.
def __init__(self, *args, **kwargs):
super(Property1Form, self).__init__(*args, **kwargs)
if self.instance.pk:
del self.fields['unit']
Then in your view, you shouldn't have to set properties.unit = unit any more. I would remove form.unit = unit as well, I don't think it was ever useful.
Trying to inherit ModelForm to create a BaseForm to update created_by, modified_by fields in model.
My BaseForm is as
class BaseForm(ModelForm):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('request', None).user
super(BaseForm, self).__init__(*args, **kwargs)
def save(self, *args, **kwargs):
kwargs['commit']=False
obj = super(BaseForm, self).save(*args, **kwargs)
if self.user:
obj.modified_by = self.user.username
obj.save()
return obj
Child Form is as
class InviteForm(BaseForm):
class Meta:
model = UserInvitation
and I am passing the request in child form through view
form = InviteForm(instance=instance,request=request)
however it gives error
TypeError at /accounts/invitation/
__init__() got an unexpected keyword argument 'request'
The error is not there if I do not inherit the BaseForm and write the code in child form i.e. InviteForm.
Please advise what I am doing wrong, I do not want to repeat the code in each form.
Traceback:
File "c:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
115. response = callback(request, *callback_args, **callback_kwargs)
File "c:\Python27\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
25. return view_func(request, *args, **kwargs)
File "C:\Python27\Lib\site-packages\django\bin\mysite\userplus\views.py" in invitation
87. form = InviteForm(instance=instance,request=request)
Exception Type: TypeError at /accounts/invitation/
Exception Value: __init__() got an unexpected keyword argument 'request'
To update the modified_by field that you have in your UserInvitation model, you should exclude it from being shown in the form:
class BaseForm(ModelForm):
...
class InviteForm(BaseForm):
class Meta:
model = UserInvitation
exclude = ('modified_by',)
Then in your view
form = InviteForm(request.POST, instance=instance)
if form.is_valid():
invite = form.save(commit=false)
invite.modified_by = request.user
invite.save()
That way the user making the request is used.
Alternatively, you can set the user beforehand:
# views.py
instance = Invite(modified_by=request.user)
form = InviteForm(request.POST, instance=instance)
...
I'm trying to create a function that list all the people who are following a particular user but I keep encountering this error which I can't seem to solve . Can someone give me a hand please :)
error
AttributeError at /Follow/
'function' object has no attribute 'objects'
Request Method: GET
Request URL: http://127.0.0.1:8000/Follow/
Django Version: 1.5.1
Exception Type: AttributeError
Exception Value:
'function' object has no attribute 'objects'
Traceback:
File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
115. response = callback(request, *callback_args, **callback_kwargs)
File "C:\Python27\lib\site-packages\endless_pagination\decorators.py" in decorated
35. return view(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
25. return view_func(request, *args, **kwargs)
"C:\mysite\pet\views.py" in Followings
97. followers = Follow.objects.followers(user)
Exception Type: AttributeError at /Follow/
Exception Value: 'function' object has no attribute 'objects'
models
class Follow(models.Model):
""" Model to represent Following relationships """
follower = models.ForeignKey(AUTH_USER_MODEL, related_name='following')
followee = models.ForeignKey(AUTH_USER_MODEL, related_name='followers')
created = models.DateTimeField(default=timezone.now)
objects = FollowingManager()
class Meta:
verbose_name = _('Following Relationship')
verbose_name_plural = _('Following Relationships')
unique_together = ('follower', 'followee')
def __unicode__(self):
return "User #%d follows #%d" % (self.follower_id, self.followee_id)
def save(self, *args, **kwargs):
# Ensure users can't be friends with themselves
if self.follower == self.followee:
raise ValidationError("Users cannot follow themselves.")
super(Follow, self).save(*args, **kwargs)
class Person(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=30, blank=True)
def __unicode__(self):
return self.user.username
views
#page_template('pagination.html')
#login_required
def Followings(request,template='following.html', extra_context=None):
followers = Follow.objects.followers(user)
person = Person.objects.filter(user__in=followers)
context = {
'page_template': 'pagination.html',
'person' :Person.objects.filter(user__in=followers),
}
extra_context = {'person':person,}
if extra_context is not None:
context.update(extra_context)
return render_to_response(
template, context, context_instance=RequestContext(request))
url
url(
r'^Follow/$',
'pet.views.Followings',
name= 'Followings',
),
change
followers = Follow.objects.followers(user)
to
followers = request.user.followers.all()