I have the following classes:
class Account(models.Model):
instance = models.OneToOneField(Instance, blank=True, null=True)
class Instance(models.Model):
is_ready = models.BooleanField(default=False, verbose_name=_('Ready?'))
Right now the relationship between Account and Instance is set by a ModelForm for Account via Account.instance.
I would like to be able to set Account.instance via a ModelForm on Instance. Is that possible?
A ModelForm is:
a helper class that lets you create a Form class from a Django model.
An idea would be to write a custom model Field to address this issue. However, according to the relevant chapter of Writing Custom Model Fields
Fields in a model must somehow be converted to fit into an existing database column type.
Trying to spot the available postgreSQL column types I found this page which does not seem to provide a solution.
On the other hand, there is an old but updated SO post, which gives a solution that actually renders both forms in an HTML page and -this way- you gather all the needed fields in one form.
forms.py
class AccountForm(forms.ModelForm):
... Do stuff if necessary ...
class Meta:
model = Account
fields = ('the_fields', 'you_want')
class InstanceForm (forms.ModelForm):
... Do other stuff if necessary ...
class Meta:
model = Instance
fields = ('the_fields', 'you_want')
views.py
...
def register(request):
if request.method == 'POST':
account_form = AccountForm(request.POST)
instance_form = InstanceForm(request.POST)
if account_form.is_valid() and instance_form.is_valid():
account_form.save()
instance_form.save()
...
the_template.html
<form action="." method="post">
{% csrf_token %}
{{ account_form.as_p }}
{{ instance_form.as_p }}
<input type="submit" value="Submit">
</form>
This is also the idea of the admin's class InlineModelAdmin.
In the admin, for example, Account will become an inline model to Instance (which is a bad name for a django class).
admin.py:
from django.contrib import admin
class InstanceInline(admin.TabularInline):
model = Instance
class AccountAdmin(admin.ModelAdmin):
inlines = [
InstanceInline,
]
Related
Could anyone explain to me similarities and differences of Django's forms.Form & forms.ModelForm?
Forms created from forms.Form are manually configured by you. You're better off using these for forms that do not directly interact with models. For example a contact form, or a newsletter subscription form, where you might not necessarily be interacting with the database.
Where as a form created from forms.ModelForm will be automatically created and then can later be tweaked by you. The best examples really are from the superb documentation provided on the Django website.
forms.Form:
Documentation: Form objects
Example of a normal form created with forms.Form:
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField()
sender = forms.EmailField()
cc_myself = forms.BooleanField(required=False)
forms.ModelForm:
Documentation: Creating forms from models
Straight from the docs:
If your form is going to be used to
directly add or edit a Django model,
you can use a ModelForm to avoid
duplicating your model description.
Example of a model form created with forms.Modelform:
from django.forms import ModelForm
from . import models
# Create the form class.
class ArticleForm(ModelForm):
class Meta:
model = models.Article
This form automatically has all the same field types as the Article model it was created from.
The similarities are that they both generate sets of form inputs using widgets, and both validate data sent by the browser. The differences are that ModelForm gets its field definition from a specified model class, and also has methods that deal with saving of the underlying model to the database.
Here's how I'm extending the builtin UserCreationForm myapp/forms.py:
from django import forms
from django.contrib.auth.forms import UserCreationForm
class RegisterForm(UserCreationForm):
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
email = forms.CharField(max_length=75)
class Meta(UserCreationForm.Meta):
fields = ('username','first_name','last_name', 'email')
The difference is simple, ModelForm serves to create the form of a Model.
meaning that Model is designed to create kind of schema of your table where you will save data from form submission and ModelForm simply creates a form of the model (from the schema of the table)
# This creates a form from model Article
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['pub_date', 'headline', 'content', 'reporter']
Form is a common form that is unrelated to your database (model ).
# A simple form to display Subject and Message field
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea)
To say in other words,
If you have a model in your app and you want to create a Form to enter data in that model (and by it to a db) use forms.ModelForm
If you simple want to create a form using django use form.Form
But you can also use this together:
from django import forms
# A simple form to display Subject and Message field
class ContactForm(forms.ModelForm):
subject = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea)
class Meta:
model = Contact #when you have this model
fields = [
'subject',
'message',
]
Could anyone explain to me similarities and differences of Django's forms.Form & forms.ModelForm?
Forms created from forms.Form are manually configured by you. You're better off using these for forms that do not directly interact with models. For example a contact form, or a newsletter subscription form, where you might not necessarily be interacting with the database.
Where as a form created from forms.ModelForm will be automatically created and then can later be tweaked by you. The best examples really are from the superb documentation provided on the Django website.
forms.Form:
Documentation: Form objects
Example of a normal form created with forms.Form:
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField()
sender = forms.EmailField()
cc_myself = forms.BooleanField(required=False)
forms.ModelForm:
Documentation: Creating forms from models
Straight from the docs:
If your form is going to be used to
directly add or edit a Django model,
you can use a ModelForm to avoid
duplicating your model description.
Example of a model form created with forms.Modelform:
from django.forms import ModelForm
from . import models
# Create the form class.
class ArticleForm(ModelForm):
class Meta:
model = models.Article
This form automatically has all the same field types as the Article model it was created from.
The similarities are that they both generate sets of form inputs using widgets, and both validate data sent by the browser. The differences are that ModelForm gets its field definition from a specified model class, and also has methods that deal with saving of the underlying model to the database.
Here's how I'm extending the builtin UserCreationForm myapp/forms.py:
from django import forms
from django.contrib.auth.forms import UserCreationForm
class RegisterForm(UserCreationForm):
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
email = forms.CharField(max_length=75)
class Meta(UserCreationForm.Meta):
fields = ('username','first_name','last_name', 'email')
The difference is simple, ModelForm serves to create the form of a Model.
meaning that Model is designed to create kind of schema of your table where you will save data from form submission and ModelForm simply creates a form of the model (from the schema of the table)
# This creates a form from model Article
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['pub_date', 'headline', 'content', 'reporter']
Form is a common form that is unrelated to your database (model ).
# A simple form to display Subject and Message field
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea)
To say in other words,
If you have a model in your app and you want to create a Form to enter data in that model (and by it to a db) use forms.ModelForm
If you simple want to create a form using django use form.Form
But you can also use this together:
from django import forms
# A simple form to display Subject and Message field
class ContactForm(forms.ModelForm):
subject = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea)
class Meta:
model = Contact #when you have this model
fields = [
'subject',
'message',
]
Background
I ran into a really annoying problem here. I've decided to use Svlete as my frontend. Also, I have a lot of endpoints in my REST api that expect form data. In the past I would just forms.py in my app's directory and then add a form like:
class ProductsModelForm(forms.ModelForm):
class Meta:
model = Product
fields = (
'name',
'weight',
)
class ProductForm(forms.Form):
name = forms.CharField()
weight = forms.IntegerField()
And would then use
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
In the HTML template. All cool.
DRF + Frontend Framework
Obviously I still have the form in the forms.py but now I have to define the form in the fronend too. And with bigger forms it gets really annoying because I always have to compare that I have every field in my frontend form that I have defined in the django backend form. Is ther any solution to this?
Use DRF SERIALIZERS.
DRF SERIALIZERS ARE JUST LIKE FORMS; THEY VALIDATE AND CLEAN DATA.
Forms are best for monolithic sites.
In my view I have a the Booking information, in the booking I have a many-to-many relationship to the size of the group in the booking and the age. The class (group size, age) has the many-to-many relationship. When the booking is made I would like the user to be able to add class details. So a booking can have many classes.
I have tried using inline_formset_factory but it did not like the many-to-many relationship and according to the docs inline_formset_factory is for a ForeignKey relationship (I could easily be wrong here). Also it seems I need a booking instance before I can use the inline_formset_factory (Though again I could be wrong)
So to recap I'm new to django and I'm trying to add many classes to a booking via a form which is with the booking form. I'm just not sure if I'm on the right track.
I hope this made sense. Thanks in advance.
Rather than creating the form yourself, instead use a ModelForm which will tie your form to a model in your app, automatically creating the field types it needs to save or edit an instance of the model it is linked with.
The simplest way to add a Booking instance to you database would be to use a ModelForm:
from django.db import models
from django.forms import ModelForm
class Booking(models.Model):
...
class BookingForm(ModelForm):
class Meta:
model = Booking
See the Django docs for more information on ModelForms. Next in your view create an instance of the BookingForm passing it in your template context:
def your_view(request):
if request.method == 'POST':
form = BookingForm(request.POST)
if form.is_valid():
booking = form.save()
return HttpResponseRedirect('/success/url/')
else:
form = BookingForm()
return direct_to_template(request, 'your/template.html', {
'form': form
})
For more information on dealing with forms in your views see using a form in a view in the Django docs. Next in your template you can simply print the entire form (and all the relevant fields) like so:
<form action="" method="post">
{{ form.as_p }}
<input type="submit" name="submit" value="submit">
</form>
See displaying a form using a template for more information on forms in templates.
Could anyone explain to me similarities and differences of Django's forms.Form & forms.ModelForm?
Forms created from forms.Form are manually configured by you. You're better off using these for forms that do not directly interact with models. For example a contact form, or a newsletter subscription form, where you might not necessarily be interacting with the database.
Where as a form created from forms.ModelForm will be automatically created and then can later be tweaked by you. The best examples really are from the superb documentation provided on the Django website.
forms.Form:
Documentation: Form objects
Example of a normal form created with forms.Form:
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField()
sender = forms.EmailField()
cc_myself = forms.BooleanField(required=False)
forms.ModelForm:
Documentation: Creating forms from models
Straight from the docs:
If your form is going to be used to
directly add or edit a Django model,
you can use a ModelForm to avoid
duplicating your model description.
Example of a model form created with forms.Modelform:
from django.forms import ModelForm
from . import models
# Create the form class.
class ArticleForm(ModelForm):
class Meta:
model = models.Article
This form automatically has all the same field types as the Article model it was created from.
The similarities are that they both generate sets of form inputs using widgets, and both validate data sent by the browser. The differences are that ModelForm gets its field definition from a specified model class, and also has methods that deal with saving of the underlying model to the database.
Here's how I'm extending the builtin UserCreationForm myapp/forms.py:
from django import forms
from django.contrib.auth.forms import UserCreationForm
class RegisterForm(UserCreationForm):
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
email = forms.CharField(max_length=75)
class Meta(UserCreationForm.Meta):
fields = ('username','first_name','last_name', 'email')
The difference is simple, ModelForm serves to create the form of a Model.
meaning that Model is designed to create kind of schema of your table where you will save data from form submission and ModelForm simply creates a form of the model (from the schema of the table)
# This creates a form from model Article
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['pub_date', 'headline', 'content', 'reporter']
Form is a common form that is unrelated to your database (model ).
# A simple form to display Subject and Message field
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea)
To say in other words,
If you have a model in your app and you want to create a Form to enter data in that model (and by it to a db) use forms.ModelForm
If you simple want to create a form using django use form.Form
But you can also use this together:
from django import forms
# A simple form to display Subject and Message field
class ContactForm(forms.ModelForm):
subject = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea)
class Meta:
model = Contact #when you have this model
fields = [
'subject',
'message',
]