could not be changed because the data didn't validate. (Django) - django

Models.py
class Produto(models.Model):
uuid = models.CharField(max_length=50, primary_key=True, editable=False, default=gen_uuid)
produto = models.CharField(max_length=100, unique=False, verbose_name="Item")
class Meta:
verbose_name = "Produto"
verbose_name_plural = "Produtos"
class Item(models.Model):
uuid = models.CharField(max_length=50, primary_key=True, editable=False, default=gen_uuid)
tipo = models.CharField(max_length=100, null=False, blank=True, unique=False, verbose_name="tipo_mtr")
class Meta:
verbose_name = "Item"
verbose_name_plural = "Itens"
class Orcamento(models.Model):
uuid = models.CharField(max_length=50, primary_key=True, editable=False, default=gen_uuid)
quantidade = models.IntegerField(max_length=10, unique=False, null=True, verbose_name="qtde")
produto = models.ForeignKey(Produto, verbose_name="Produto")
tipo = models.ManyToManyField(Item, verbose_name="Item")
class Meta:
verbose_name = "Orcamento"
verbose_name_plural = "Orcamentos"
unique_together = ("produto", "uuid")
def __unicode__(self):
return unicode(self.produto)
My forms.py (OrcamentoForm)
class OrcamentoForm(ModelForm):
tipo_id = ModelMultipleChoiceField(queryset=Item.objects.all(), required=True, widget=SelectMultiple(attrs={"style":"width:500px",}), help_text="Coloque o Tipo de Medida - Requerido")
quantidade = IntegerField(label="Quantidade", required=True, help_text="Coloque a Quantidade - Requerido")
produto_id = ModelMultipleChoiceField(queryset=Produto.objects.all(), widget=SelectMultiple(attrs={"style":"width:500px",}), required=True, help_text="Escolha o Produto - Requerido")
def __init__(self, *args, **kwargs):
super(OrcamentoForm, self).__init__(*args, **kwargs)
# without the next line label_from_instance does NOT work
self.fields['produto_id'].queryset = Produto.objects.all()
self.fields['produto_id'].label_from_instance = lambda Produto: "%s" % (Produto.produto)
self.fields['tipo_id'].queryset = Item.objects.all()
self.fields['tipo_id'].label_from_instance = lambda Item: "%s" % (Item.tipo)
class Meta:
model = Orcamento
fields = ["quantidade", "tipo_id", "produto_id" ]
My views.py
def orcamento(request):
form = OrcamentoForm(request.POST or None, request.FILES or None)
if request.method == 'POST':
form.save()
return render_to_response("webSite/teste.html", context_instance = RequestContext(request))
else:
return render_to_response("webSite/orcamento.html", {"form": form }, context_instance=RequestContext(request))
With if form.is_valid(): in views.py, don't save form in table mysql.
Help-me :(

If form is not getting saved when you perform a check of form.is_valid() means the form was invalid. In such cases, we should display the errors found by the form for every field. For that to happen, first you should pass form data to templates, if form is invalid.
#views.py
def orcamento(request):
form = OrcamentoForm(request.POST or None, request.FILES or None)
if request.method == 'POST':
if form.is_valid():
form.save()
return render_to_response("webSite/teste.html", context_instance = RequestContext(request))
#Following will run in all cases except when form was valid
return render_to_response("webSite/orcamento.html", {"form": form }, context_instance=RequestContext(request))
You can display all the errors thrown by the form or field-wise errors in your template. See the django documentation detailed understanding.

The same error occurred when I mistyped
.is_valid() as .is_valied().
You might wanna check whether it's the case.

This error can also occur if you never included the () in .is_valid(). Having the validity checker as .is_valid: also raises the same error.

This error happened to me but I solved by adding parentheses to is_valid and it became is_valid() and the error went and never come back

Related

how to apply constraints on Django field within the instances associated with the user

I am making a todo app for practice, the functionality I want to achieve is that, when a user create a task,Only the time field should be unique about all of his tasks, I have done (unique=True) In the time field in model but that make it unique all over the database, but I want it to be unique only with the tasks associated with the user.
the view is below:
#login_required(login_url='login')
def home(request):
tasks = Task.objects.filter(name__username=request.user.username)
form = TaskForm()
if request.method == 'POST':
form = TaskForm(request.POST)
if form.is_valid():
obj = form.save(commit=False)
obj.name = request.user
obj.save()
return redirect('home')
else:
print(request.POST)
print(request.user.username)
messages.warning(request, 'Invalid Data!')
return redirect('home')
context = {'tasks' : tasks}
return render(request, 'task/home.html', context)
task model:
class Task(models.Model):
choices = (
('Completed', 'Completed'),
('In Complete', 'In Complete'),
)
name = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
task = models.CharField(max_length=200, null=False, blank=False)
time = models.TimeField(auto_now_add=False, blank=True)
status = models.CharField(max_length=200, choices=choices, null=True, blank=False)
def __str__(self):
return self.task
def get_task_author_profile(self):
return reverse('profile')
as you can see, I want to show the task that the logged in user has added.
the form is:
class TaskForm(ModelForm):
class Meta:
model = Task
fields = '__all__'
exclude = ['name']
the functionality I talked about above, I tried to achieve through view:
#login_required(login_url='login')
def home(request):
tasks = Task.objects.filter(name__username=request.user.username)
time = []
for task in tasks:
time.append(task['time'])
form = TaskForm()
if request.method == 'POST':
form = TaskForm(request.POST)
if form.is_valid() and form.cleaned_data['time'] != time:
obj = form.save(commit=False)
obj.name = request.user
obj.save()
return redirect('home')
else:
print(request.POST)
print(request.user.username)
messages.warning(request, 'Invalid Data!')
return redirect('home')
context = {'tasks' : tasks}
return render(request, 'task/home.html', context)
but that gave an error: TypeError: 'Task' object is not subscriptable
I know its not right, but how can I achieve it, does Django have anything that can provide such fuctionality?
The problem is coming from here:
for task in tasks:
time.append(task['time']) #<--
Here if you want to use access time, you need to use task.time because task is an object.
Also need to fix another thing in your exisiting code to make it work, because time is a list:
if form.is_valid() and form.cleaned_data['time'] in time:
# ^^^
BTW, you don't need to make it that complicated, you can add Database level constraint from the model to make the times unique for a specific user. Also, use DateTime field for that. You can use unique_togather for that:
class Task(models.Model):
choices = (
('Completed', 'Completed'),
('In Complete', 'In Complete'),
)
name = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
task = models.CharField(max_length=200, null=False, blank=False)
time = models.DateTimeField(auto_now_add=False, blank=True)
status = models.CharField(max_length=200, choices=choices, null=True, blank=False)
class Meta:
unique_togather = ['name', 'time']

LeaveApplyForm' object has no attribute 'save'

I want to save a leave in database applied from employee but when i was submit i faced this error ----LeaveApplyForm' object has no attribute 'save'---
**models.py**
class All_Leaves(models.Model):
leave_types = models.ForeignKey(Leave_Types, on_delete=models.CASCADE, related_name="all_leave")
user = models.ForeignKey(MyUser, on_delete=models.CASCADE, related_name="all_leave")
reason = models.CharField(('Reason'), max_length=120)
start_date = models.DateTimeField(('Start Date'),auto_now = True)
end_date = models.DateTimeField(('End Date'),auto_now = True)
class Meta:
verbose_name = ("All Leave")
verbose_name_plural = ("All Leaves")
**View.py**
def apply_leave(request):
print("user",request.user)
print("data",request.POST)
leave_type_data = Leave_Types.objects.all()
if request.method =="POST":
form = LeaveApplyForm(request.POST, None)
print("form status",form.is_valid())
if form.is_valid():
form.save(leave_types=request.POST['leave_types'], user=request.user)
print("form in")
return render(request, 'dashboard.html',{"var_leave":"false","leave_type_data":leave_type_data})
else:
print("form errors",form.errors)
return render(request, 'dashboard.html',{"var_leave":"false","leave_type_data":leave_type_data,"form":form})
forms.py
class LeaveApplyForm(forms.Form):
start_date = forms.DateTimeField(required=True, error_messages={'required': 'Please Choose Start Date.'})
end_date = forms.DateTimeField(required=True, error_messages={'required': 'Please Select End Date.'})
reason = forms.CharField(required=True, error_messages={'required': 'Please Enter Your Reason.'})
class Meta:
model = All_Leaves
fields = ('start_date','end_date','reason')
You've inherited from forms.Form instead of forms.ModelForm.

Django - How to add sender-name in Email?

What I am trying to achieve is having the senders-name, from the current logged in user with the association name, to show up in the receivers inbox like so:
'associaton-name'#domain.com
I have commented it down below where i tried to achieve it in views.py
Can't seem to find any related solutions after days and hours of work.
Really appreciate your help, folks!
Django: 1.10
Python: 3.6
views.py
class mailPost(FormView):
success_url = '.'
form_class = mailHandler
template_name = 'post/post.html'
def form_valid(self, form):
messages.add_message(self.request, messages.SUCCESS, 'Email Sent!')
return super(mailPost, self).form_valid(form)
def form_invalid(self, form):
messages.add_message(self.request, messages.WARNING,
'Email not sent. Please try again.')
return super(mailPost, self).form_invalid(form)
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
if form.is_valid():
sender = "noreply#domain.com" # Instead of noreply I wish for current requested associaton name
receiver = form.cleaned_data.get('receiver')
cc = form.cleaned_data.get('cc')
bcc = form.cleaned_data.get('bcc')
subject = form.cleaned_data.get('subject')
message = form.cleaned_data.get('message')
time = datetime.now()
asoc_pk = Association.objects.filter(asoc_name=self.request.user.association)
asoc = Association.objects.get(id=asoc_pk)
Email.objects.create(
sender=sender,
receiver=receiver,
cc=cc,
bcc=bcc,
subject=subject,
message=message,
association=asoc,
sentTime=time
)
msg = EmailMultiAlternatives(subject, message, sender, [receiver], bcc=[bcc], cc=[cc])
msg.send()
return self.form_valid(form)
else:
return self.form_invalid(form)
models.py
class Email(models.Model):
sender = models.CharField(max_length=254)
sentTime = models.DateTimeField(auto_now_add=True, blank=False)
subject = models.CharField(max_length=254)
receiver = models.CharField(max_length=254)
cc = models.CharField(max_length=254)
bcc = models.CharField(max_length=254)
message = models.TextField()
association = models.ForeignKey(Association)
class Meta:
db_table = 'Email'
class Association(models.Model):
asoc_name = models.CharField(max_length=50, null=True, blank=True, unique=True)
class Meta:
db_table = 'Association'
class Administrator(AbstractUser):
...
association = models.ForeignKey(Association)
class Meta:
db_table = 'Administrator'
I'm not sure I understand your question correctly. You can access the authenticated user (given you are using the Django Authentication system) by calling self.request.user.
You have to create a relation between Association and the user:
class Association(models.Model):
asoc_name = models.CharField(max_length=50, null=True, blank=True, unique=True)
# Option 1 - if one user can be a member of several associations
members = models.ManyToMany(User)
class Meta:
db_table = 'Association'
or a new model instance if a user can only be a member of one association:
# Option 2
class Membership(Model):
association = models.ForeignKey(Association)
user = models.ForeignKey(User, unique=True)
You get the Association using a direct lookup (or a reverse relation).
# option 1
if form.is_valid():
sender = Association.objects.filter(members=self.request.user).first()
# sender might be None
# option 2
if form.is_valid():
membership = Membership.objects.filter(user=self.request.user).first()
if membership:
sender = membership.association
https://docs.djangoproject.com/en/1.11/topics/db/examples/many_to_many/

How to input a model instance in a form field

I have a simple model with 2 classes:
class Company(models.Model):
company_name = models.CharField(default='', max_length=128, blank=True, null=True)
class Visitor(models.Model):
visitor_company = models.ForeignKey(Company)
visitor_name = models.CharField(default='', max_length=128, blank=False, null=False)
I also have a simple form:
class VisitorForm(forms.ModelForm):
visitor_company = forms.CharField()
class Meta:
model = Visitor
fields = "__all__"
And here is the view.py code:
def home(request):
form = Visitor()
if request.method == "POST":
form = Visitor(request.POST)
if form.is_valid():
obj, created = Visitor.objects.get_or_create(**form.cleaned_data)
if created:
messages.add_message(request, messages.SUCCESS, 'Visitor added.')
else:
messages.add_message(request, messages.INFO, 'Visitor exists : %s' % obj.visitor_name)
return redirect('visitors')
context = { 'form': form }
return render(request, "visitors/home.html", context)
I have set visitor_company as a CharField as I want to use Typeahead for users to specify the ForeignKey, rather than Django's built in dropdown (which would appear if I did not set the input type).
However, when I use this method, even if I input a valid company_name in the visitor_company field, I get Cannot assign "XXX": "Visitor.visitor_company" must be a "Company" instance.
How do I input a Company instance? Is it also possible to use get_or_create on a ForeignKey like this if the Company record doesn't exist?
This is untested code, so consider this a starting point, no real solution:
forms.py
class VisitorForm(forms.ModelForm):
visitor_company = forms.CharField()
def clean_visitor_company(self):
vc = self.cleanded_data['visitor_company']
try:
vc_object = Company.objects.get(company_name=vc)
except Company.DoesNotExist:
vc_object = Company.objects.create(company_name=vc)
return vc_object
class Meta:
model = Visitor
fields = "__all__"
views.py
def home(request):
form = VisitorForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('visitors')
return render(request, "visitors/home.html", { 'form': form })

saving django ManyToMany not valid

I have a form from my model that needs to be validated and saved making use of ManyToMany Fields.
Everytime I try and save it, I get thrown back to the page, just saying this field is required
My models.py
class HuntingReport(models.Model):
user = models.ForeignKey(User, related_name='User')
outfitter = models.ForeignKey(User, related_name='Outfitter', null=True, blank=True)
date_travel_started = models.DateField(blank=True, null=True)
date_travel_ended = models.DateField(null=True, blank=True)
title = models.CharField(max_length=50)
report = models.TextField()
wish_list = models.ManyToManyField(Specie)
bag_list = models.ManyToManyField(Trophies)
def __unicode__(self):
return self.title
My forms.py looks as follows
class HuntingReportForm(ModelForm):
date_travel_started = forms.DateField(widget=extras.SelectDateWidget(years=range(1970,2010)))
date_travel_ended = forms.DateField(widget=extras.SelectDateWidget(years=range(1970,2010)))
wish_list = forms.ModelMultipleChoiceField(queryset=Specie.objects.all(), widget=FilteredSelectMultiple("verbose name", is_stacked=False))
bag_list = forms.ModelMultipleChoiceField(queryset=Trophies.objects.all(), widget=FilteredSelectMultiple("verbose name", is_stacked=False))
class Meta:
model = HuntingReport
exclude = ['user']
def __init__(self, user, *args, **kwargs):
super(HuntingReportForm, self).__init__(*args, **kwargs)
users = User.objects.filter(userprofile__outfitter=True)
self.fields['outfitter'].choices = [('', '')] + [(user.pk, user.get_full_name()) for user in users]
my views.py
def create(request, template_name='reports/new.html'):
if request.method == 'POST':
form = HuntingReportForm(request.POST, request.FILES)
if form.is_valid():
newform = form.save(commit=False)
newform.user = request.user
newform.save_m2m()
return HttpResponseRedirect('/hunting-reports/')
else:
form = HuntingReportForm(request.user)
context = { 'form':form, }
return render_to_response(template_name, context,
context_instance=RequestContext(request))
Did you try passing blank=True for model field's constructor, or required=False for the ModelMultipleChoiceField's constructor?
I know that blank=True solves the problem for the form in the admin panel, but I don't know how it gets mapped to the ModelForm's fields. I'm assuming that it gets mapped to required property.