object has no attribute 'is_valid' - python

I am receiving an error, object has no attribute 'is_valid', when trying to insert form data into a form. Below is the structure of my code:
model.py
view.py
index.html

fm = Reg() doesn't really make sense. You can't assign a model/instance to a variable and consider it a form. Instead, create a form based on your model like this:
Create a file forms.py and create a ModelForm in it:
from django.forms import ModelForm
from mysite.models import Reg
class RegForm(ModelForm):
class Meta:
model = Reg
fields = ('<field_names>',)
ModelForm let's you create a form based on your Model.
Now import this in your views.py and use RegForm instead of Reg.

Related

AttributeError: (Class) object has no attribute '__name__' Creating ModelForms [Django & Python2.7]

This is my first time using Django and I am completely stuck at how to use ModelForms in my project. I have been able to follow the online tutorials this far but without ModelForms(to add data into a Postgresql database), I can't proceed onward. I am trying to simply make a form page that lets the users add a few inputs (2 datefields and 1 textfield) and by submitting that form, the data will be added to the database.
The error I have been getting is:
AttributeError: 'Hyuga_Requests' object has no attribute 'name' [where Hyuga_Request is a class set in the models.py]
models.py
from __future__ import unicode_literals
from django.db import models
from django.forms import ModelForm
class Hyuga_Requests(models.Model):
name = models.CharField(max_length=50)
s_date = models.DateField(auto_now=True)
e_date = models.DateField(auto_now=True)
reason = models.TextField(max_length=500)
def __unicode__(self):
return self.name
views.py
from django.shortcuts import render
from django import forms
from .forms import Hyuga_RequestForm
def create_req(request):
form = Hyuga_RequestForm()
context = {"form":form,}
return render(request,"request_form/requestform.html", context)
forms.py
from django import forms
from .models import Hyuga_Requests
from django.forms import ModelForm
class Hyuga_RequestForm(forms.ModelForm):
class Meta:
model = Hyuga_Requests()
fields = ['name','s_date','e_date','reason']
Please help this noobie...
Don't instantiate the model in the class Meta inside the Hyuga_RequestForm class.
model = Hyuga_Requests() should be model = Hyuga_Requests
model = Hyuga_Requests() -> model = Hyuga_Requests
The error come because you are calling the model on the form.
from django import forms
from .models import Hyuga_Requests
from django.forms import ModelForm
class Hyuga_RequestForm(forms.ModelForm):
class Meta:
model = Hyuga_Requests
fields = ['name','s_date','e_date','reason']
Note: i suggest to you use on the any class you define on python not use "_", you can check more about PEP8 and code styles here: https://www.python.org/dev/peps/pep-0008/

Python/Django - Generating forms for models.

I have two questions concerning models and forms.
1) What is the best way to create automatically forms for the models?
In the example below I have two models - ModelA and ModelB. I need forms for them - ModelAForm and ModelBForm. They should be defined automatically. I do not want to do it manually, because in the future I will add other models, and all the forms will look the same. I am thinking about creating special decorator for models and use modelform_factory.
from django.db import models
from django.forms import ModelForm
class ModelA(models.Model):
...
class ModelB(models.Model):
...
class ModelAForm(ModelForm):
class Meta:
abstract = ModelA
class ModelBForm(ModelForm):
class Meta:
abstract = ModelB
2) Assuming I am using only ModelForm forms, it is possible to find the form for the model? Example. I have two models ModelA and ModelB, and two forms ModelAForm and ModelBForm. I have instance of ModelA and I would like to identify proper form for this model which I will pass to template - in this case ModelAForm.
Django provides some generic editing views. You only have to provide a model and the view will generate the form automatically. If you want to use the forms to create or update instances you can just use them.
If your really need to create the forms yourself you can use the modelform_factory that these views use themself to create the correct form for your model. But i would first go with the generic views as long as they can be modified to suit your needs.
Just pass it your model and optionally the fields you want. If you omit the fields, all fields will be generated:
from .models import MyModel
from django.forms.models import modelform_factory
my_form = modelform_factory(MyModel, fields=['name', 'age', 'job'])
There's ModelForm in django.
Here's fragment of documentation and link for it.
https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['pub_date', 'headline', 'content', 'reporter']
You're probably looking for generic class-based views, where you only pass form_class and model instances, everything else django handles without your help.
Link for them - https://docs.djangoproject.com/en/1.10/ref/class-based-views/

Django add an attribute class form in __init__.py

My form class
from django import forms
class Form(forms.Form):
your_name = forms.CharField(label='Your name ', max_length=100)
My app file __init__.py
from django import forms
from my_app.forms import Form
from captcha.fields import ReCaptchaField
def register(form):
form.captcha=CaptchaField()
register(Form)
Code in __init__.py add an attribute captcha but it is not on the page.
I tried so
My form class
from django import forms
class Form(forms.Form):
your_name = forms.CharField(label='Your name ', max_length=100)
captcha=CaptchaField()
It works, but I have a different! I want to add a сaptcha many forms.
I want to add the captcha without changing the form classes. I want to change the form classes during initialization.
How to do it???
You need to assign the field to form.fields, not just form.
However this is not really the way to do this. Instead, you should make all your forms inherit from a shared parent class, which defines the captcha field.
Continuing from a comment, have a base class inherit from django.forms.Form, and subclass it for all the forms you want a captcha field on;
from captcha.fields import ReCaptchaField
from django.forms import Form
class CaptchaMixin():
captcha = ReCaptchaField()
class ActualForm(CaptchaMixin, Form):
pass

Error while creating a django forms from a list.

Error:
'list' object has no attribute '_meta'
forms.py:
from django.db import models
from django.forms import ModelForm
from django import forms
class Blog(models.Model):
blog_id = models.CharField(max_length=100)
class TumblrForm(ModelForm):
class Meta:
model = Blog
fields = ('blog_id',)
widgets = {
'blog_id':forms.RadioSelect(),
}
Form creation:
form = TumblrForm(instance=blogs_id) #blogs_id is a list of blog urls
Where am I going wrong?
A ModelForm edits one instance. You can't pass it a list of urls. It needs an instance of Blog.
TumblrForm(instance=Blog.objects.get(pk=1))
If you want to edit multiple ModelForms, you'll want to look into django's FormSet.

How to add custom fields to InlineFormsets?

I'm trying to add custom fields to an InlineFormset using the following code, but the fields won't show up in the Django Admin. Is the InlineFormset too locked down to allow this? My print "ding" test fires as expected, I can print out the form.fields and see them all there, but the actual fields are never rendered in the admin.
admin.py
from django.contrib import admin
import models
from django.forms.models import BaseInlineFormSet
from django import forms
from forms import ProgressForm
from django.template.defaultfilters import slugify
class ProgressInlineFormset(BaseInlineFormSet):
def add_fields(self, form, index):
print "ding"
super(ProgressInlineFormset, self).add_fields(form, index)
for criterion in models.Criterion.objects.all():
form.fields[slugify(criterion.name)] = forms.IntegerField(label=criterion.name)
class ProgressInline(admin.TabularInline):
model = models.Progress
extra = 8
formset = ProgressInlineFormset
class ReportAdmin(admin.ModelAdmin):
list_display = ("name", "pdf_column",)
search_fields = ["name",]
inlines = (ProgressInline,)
admin.site.register(models.Report, ReportAdmin)
I did it another way:
forms.py:
from django import forms
class ItemAddForm(forms.ModelForm):
my_new_field = forms.IntegerField(initial=1, label='quantity')
class Meta:
model = Item
admin.py:
from django.contrib import admin
from forms import *
class ItemAddInline(admin.TabularInline):
form = ItemAddForm
fields = (..., 'my_new_field')
This works so far, I only need to override somehow the save method to handle this new field. See this: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#form . It says that by default Inlines use BaseModelForm, which is send to formset_factory. It doesn't work for me, tried to subclass BaseModelForm with errors (no attribute '_meta'). So I use ModelForm instead.
You can do it by another way (Dynamic forms):
admin.py
class ProgressInline(admin.TabularInline):
model = models.Progress
extra = 8
def get_formset(self, request, obj=None, **kwargs):
extra_fields = {'my_field': forms.CharField()}
kwargs['form'] = type('ProgressForm', (forms.ModelForm,), extra_fields)
return super(ProgressInline, self).get_formset(request, obj, **kwargs)
model = models.Progress
In the admin there will be only the fields defined in this Progress model. You have no fields/fieldsets option overwriting it.
If you want to add the new ones, there are two options:
In the model definition, add those new additional fields (make them optional!)
In the admin model (admin.TabularInline), add something something like:
fields = ('newfield1', 'newfield2', 'newfield3')
Take a look at fields, fieldsets.

Categories