from django import forms
from .models import NewsSignUp
class NewsSignUpForm(forms.ModelForm):
class Meta:
model = NewsSignUp
fields = ['email', 'first_name']
here
This code works perfectly fine. But, when I remove "class Meta:" as below, it throws a ValueError saying "ModelForm has no model class specified."
from django import forms
from .models import NewsSignUp
class NewsSignUpForm(forms.ModelForm):
model = NewsSignUp
fields = ['email', 'first_name']
Can someone please give an explanation? :(
You are creating a ModelForm subclass. A model form has to have a model to work from, and the Meta object configures this.
Configuration like this is grouped into the Meta class to avoid name clashes; that way you can have a model field in your form without that interfering with the configuration. In other words, by using class Meta: you get a nested namespace used just to configure the ModelForm in relation to the model.
The namespace for the ModelForm class body itself then (outside Meta) is reserved for the form fields themselves, as well as form methods. You'd normally just let ModelForm generate those fields from your model, but you can, in principle, add fields to this. Another reason to put fields in the class is to completely replace any of the generated fields with your own version.
From the Model Forms documentation:
ModelForm is a regular Form which can automatically generate certain fields. The fields that are automatically generated depend on the content of the Meta class and on which fields have already been defined declaratively. Basically, ModelForm will only generate fields that are missing from the form, or in other words, fields that weren’t defined declaratively.
Fields defined declaratively are left as-is, therefore any customizations made to Meta attributes such as widgets, labels, help_texts, or error_messages are ignored; these only apply to fields that are generated automatically.
Because ModelForm expects the configuration to be set under the Meta name, you can't just remove that and put model and fields in the ModelForm class itself; that's just the wrong place.
Related
So, I have a ModelAdmin that I need to add extra fields to. These fields do not exist on the model, but will be dynamically added to a custom ModelForm through the init method, and logic inside clean will handle the returned data on save.
I can't seem to find any solid information related to adding custom non-model fields to a ModelAdmin form. The closest I have come is by overriding get_fields on the ModelAdmin class and updating self.form.declared_fields with the new fields I'd like to add.
This just doesn't feel very clean to me and I was curious if there was a better way to add new fields to a ModelAdmin dynamically?
You can also use this way to add fields not in the models.py
in admin.py:::
from django.utils.translation import gettext as _
class TrialAdmin(admin.ModelAdmin):
fields = (..., 'non_model_field',...,)
def non_model_field(self, instance):
# this method name should be same as new field name defied above in fields.
# [what u need to do here]
non_model_field.short_description = _("non_model_field")
#This value 'short_description' defines what the field name is shown as in admin similar to 'verbose_name' in models.
admin.site.register(..., TrialAdmin)
I have one model that has a ManyToMany Field (let's call it "Options") with another Model
When I create the ModelForm it displays all options.
Is there any way to exclude some option values or to show only some of them?
Here is an example:
models.py
class Options (model.Models):
name = ...
...
class Anything (model.Models):
...
options = ManyToManyField(Options)
values of "Options" in my DB:
["OK",
"OK_2",
"NOT_OK",
"OK_3,
"NOT_OK_2"]
Let's say that I need to show ONLY the "OK" values and hide or not to show the "NOT_OK" values.
Is there any way to do this with ModelForms?
You certainly can filter the queryset for a foreign key field or m2m on the related model by using a Form or more commonly a ModelForm.
The reason doing this at form level is useful is because that filtering could well be based on business logic which is not applicable in all cases and so allows more flexibility than defining it against the model for example.
While you can do this while defining the form fields it is best to do it once the form has been constructed and so it takes place at runtime and not compile time (I have just experienced a few interesting occasions where this has caused me some issues, however that was an earlier version of Django!)
The following ModelForm would do the job:
class AnythingForm(ModelForm):
options = forms.MultipleChoiceField()
def __init__(self, **kwargs):
super(AnythingForm, self).__init__(self, **kwargs)
self.fields['options'].queryset = Option.objects.filter({pass in your filters here...})
class Meta:
model = Anything
You can pass the limit_choices_to parameter to your ManyToMany field:
from django.db.models import Q
class Anything (models.Model):
options = models.ManyToManyField(Options,
limit_choices_to=Q(name__startswith='OK'))
In django 1.7 you can even pass a callable in case if list of choices should be changed dynamically.
How can I use two models with OneToOne relation in one form using the CreateView in Django 1.5?
My models are these:
class Act(models.Model):
name = models.CharField()
class DetailAct(models.Model):
detail = models.CharField()
act = models.OneToOneField(Act)
My forms
class ActForm(forms.ModelForm):
name = forms.CharField(widget=forms.TextInput())
class Meta:
model = models.Act
class DetailActForm(forms.ModelForm):
detail = forms.CharField(widget=forms.TextInput())
class Meta:
model = models.DetailAct
Thank you
You can use two Form objects in one <form> tag without problems. Just make sure that you pass prefix="form-1" to one of the forms (or both - as long as the prefixes are different) in your view. See this answer for an example.
Nope, you can't use built-in class based views for this. Or, at least, not on the high-level you'd expect. You can make your own view class or mixin that will work with two forms, but AFAIK Django doesn't provide one.
I've defined a models.py with a "FirstClass" which contains a ForeignKey relathionship to "SecondClass". The relathionship can't be Null.
The SecondClass is very expansive (90.000 records), and when i display the FirstClass html form, it requires too many time generating the "select box" field.
Therefore, when I let user update the object (I use create_update.update_object generic view), i don't want to display and update the value of the foreignkey field, but i don't know how to do this...
Create a ModelForm and pass it into the view, according to the docs.
Since the foreign key should always exist upon creation, it's safe to ignore it in the update.
class MyModelForm(forms.ModelForm):
class Meta:
model = FirstClass
exclude = ('SecondClass',)
# urls.py
(r'^foo/(?P<object_id>\d+)/$','django.views.generic.create_update.update_object',
{'form_class': MyModelForm})
I'm building a formset like so:
InterestFormSet = modelformset_factory(Interest, \
formset=BaseInterestFormSet, exclude=('userid',), extra=2)
And I want set default labels and values for elements of this form.
I know that in simple forms I can use the fields dict to change these things for specific fields of the form, but how is this done with a formset?
I tried extending the formset (as you can see) to see if I could access self.fields from within __init__, but no luck.
Something like this should do what you want:
class InterestForm(ModelForm):
pub_date = DateField(label='Publication date')
class Meta:
model = Interest
exclude = ('userid',)
InterestFormSet = modelformset_factory(Interest, form=InterestForm, extra=2)
Formsets don't have fields, they only have forms which have fields. So you have to deal directly with those forms.