ModelForm won't create instance of model - python

I am trying to create a frontend form in my Django site that will allow users to add entries to my SQL database.
But when I use the form nothing happens in my database. What am I doing wrong?
I thought the right way would be to use the ModelForm technique.
My models looks like this:
class Actor(models.Model):
name = models.CharField(max_length=200)
wage = models.IntegerField(default=3100)
def __str__(self):
return self.name
So I wrote this in my forms.py:
from django import forms
from .models import Actor
class ActorForm(forms.ModelForm):
class Meta:
model = Actor
fields = ['name', 'wage']
form = ActorForm()
I then added this to my views.py:
def get_actor(request):
if request.method == 'POST':
form = ActorForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/scenes/thanks/')
else:
form = ActorForm()
return render(request, 'scenes/actor.html', {'form': form})
def thanks(request):
return render(request, 'scenes/thanks.html',)
And this in a template called actors.html
<form action="/scenes/actor/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />

You have to call the model form's save() method after checking that it's valid:
def get_actor(request):
if request.method == 'POST':
form = ActorForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/scenes/thanks/')
else:
form = ActorForm()
return render(request, 'scenes/actor.html', {'form': form})

Related

provide the same instance of one form to the other

Updated
i have two tables(models) one for product name and features and the other for prices
i normalized to database tables
like this
class Model(models.Model):
name = models.CharField(max_length=23)
def __str__(self):
return self.name
class Feature(models.Model):
model = models.ForeignKey(Model,on_delete=models.CASCADE)
price = models.IntegerField()
company = models.CharField(max_length=33)
def __str__(self):
return self.model
my views.py
def create(request):
createmodel = ModelForms(prefix='createmodel')
createfeature = FeatureForm(prefix='createfeature')
if request.method == 'POST':
createmodel = ModelForms(request.POST,prefix='createmodel')
if createmodel.is_valid():
createmodel.save()
name = createmodel.cleaned_data['name']
if createfeature.is_valid():
createfeature = FeatureForm(request.POST,prefix='createfeature',model=name)
createfeature.save()
return redirect('/lists/')
return render(request,'forms/create.html',{'createmodel':createmodel,'createfeature':createfeature})
my forms.py
class ModelForms(forms.ModelForm):
class Meta:
model = Model
fields = [
'name'
]
class FeatureForm(forms.ModelForm):
read_only = ['model']
class Meta:
model = Feature
fields = [
'price','company'
]
but the form wont saved
how to submit both forms at the same time with providing the exact foreign key (as filled in ModelForm to FeatureForm)in one go
i know how to do it in updating two forms , but how to create submit two forms with providing the instance directly
much respect
Doing it is simple, since you did not provide views.py and .html I had to give you my example.
views.py
def (request):
if request.method == 'POST':
# PROCESS POST METHOD FORM
user_form = UserEditForm(instance=request.user, data=request.POST)
profile_form = ProfileEditForm(instance=request.user.profile_user, data=request.POST, files=request.FILES)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
else:
# HERE WE ADD TWO FORMS IN CONTEXT
user_form = UserEditForm(instance=request.user)
profile_form = ProfileEditForm(instance=request.user.profile_user)
return render(request, 'accounts/edit.html', {'user_form': user_form, 'profile_form': profile_form})
edit.html
<!-- Above Code -->
<form action="." method="post" enctype="multipart/form-data">
{{ user_form.as_p }}
{{ profile_form.as_p }}
{% csrf_token %}
<p><input type="submit" value="Save changes"></p>
</form>
<!-- Below Code -->
You can make two separate forms for two models.
Its better to use form prefix in such cases, in my case it will become:
def (request):
if request.method == 'POST':
# PROCESS POST METHOD FORM
user_form = UserEditForm(request.POST, prefix="user_form")
profile_form = ProfileEditForm(request.POST, prefix="profile_form", files=request.FILES)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
else:
# HERE WE ADD TWO FORMS IN CONTEXT
user_form = UserEditForm(prefix="user_form")
profile_form = ProfileEditForm(prefix="profile_form")
return render(request, 'accounts/edit.html', {'user_form': user_form, 'profile_form': profile_form})

How to pre-populate form with data received from a previous HTML form submission in Django?

I'm trying to populate my ModelForm with some of data that I have submitted to previous HTML page which is also ModelForm.
I just want to pass it to another form so it doesn't have to be written twice.
I've tried couple solutions from stackoverflow but they are 6+ years old, kinda outdated and also couldnt come up with solution from django docs https://docs.djangoproject.com/en/2.2/topics/forms/
I have two models, which have same fields which are name and boxid
I need to pass it from first input to second(to populate it).
forms.py
class NewCashierForm(forms.ModelForm):
class Meta:
model = Cashier
fields = ("cashier_company", "cashier_dealer", "cashier_name", "cashier_boxid", "cashier_type", "cashier_package", "cashier_otheritem", "cashier_otheritemserial", "cashier_length", "cashier_promotion", "cashier_amount", "cashier_paymenttype")
labels = {"cashier_company":('Firma'), "cashier_dealer": ('Diler'), "cashier_name":('Ime i prezime'), "cashier_boxid":('Box ID'), "cashier_type":('Tip'), "cashier_package":('Paket'), "cashier_otheritem":('Drugi uredjaj'), "cashier_otheritemserial":('SBU'), "cashier_length":('Dužina'), "cashier_promotion":('Promocija'), "cashier_amount":('Iznos'), "cashier_paymenttype":('Nacin uplate')}
exclude = ['cashier_published']
def save(self, commit=True):
cashier = super(NewCashierForm, self).save(commit=False)
if commit:
cashier.save()
return cashier
class NewPersonForm(forms.ModelForm):
class Meta:
model = Person
fields = {"person_name", "person_adress", "person_phone", "person_boxid"}
labels = {"person_name":('Ime i prezime'), "person_adress":('Adresa'), "person_phone":('Telefon'), "person_boxid":('Box ID')}
def save(self, commit=True):
person = super(NewPersonForm, self).save(commit=False)
if commit:
person.save()
return person
views.py
def addcashier(request):
if request.method == 'GET':
form = NewCashierForm()
else:
form = NewCashierForm(request.POST)
if form.is_valid():
fs = form.save(commit=False)
fs.user = request.user
fs.save()
return redirect('/byauthor')
return render (request, 'main/addcashier.html', {'form':form})
def addperson(request):
if request.method == 'GET':
form = NewPersonForm()
else:
form = NewPersonForm(request.POST)
if form.is_valid():
fs = form.save(commit=False)
fs.user = request.user
fs.save()
return redirect('/addcashier')
return render (request, 'main/addperson.html', {'form':form})
addperson.html and addcashier.html
{% extends "main/base.html" %}
{% block content %}
<form method="POST">
{% csrf_token %}
{{form.as_p}}
<button class="btn" type="submit">Unos i dodavanje pretplate</button>
</form>
<input type="button" value="Otkazi unos" onclick="window.history.back()" />
{% endblock %}
Any help and/or hint is appreciated.
To prepopulate the form, you need to pass an argument initial={} when initializing your form for the GET call. Since you are passing data from one view to another, you should use sessions.
def addperson(request):
if request.method == 'GET':
form = NewPersonForm()
else:
form = NewPersonForm(request.POST)
if form.is_valid():
fs = form.save(commit=False)
fs.user = request.user
fs.save()
request.session["person_form"] = request.POST.dict() #save the form as a dict in request.sessions
return redirect('/addcashier')
return render (request, 'main/addperson.html', {'form':form})
Then in your second view, use this data from sessions to initialize the form.
def addcashier(request):
if request.method == 'GET':
# get the form data from the request.session
form_data = request.session.pop('person_form', {})
box_id = form_data.get("person_boxid")
name = form_data.get("person_name")
form = NewCashierForm(initial={"cashier_name":name, "cashier_boxid":box_id}) # initialize the form with the data
else:
form = NewCashierForm(request.POST)
if form.is_valid():
fs = form.save(commit=False)
fs.user = request.user
fs.save()
return redirect('/byauthor')
return render (request, 'main/addcashier.html', {'form':form})

Passing query string to ModelForm hidden field - Django

I want to pass a query string e.g., ?refcode='A1234' to a hidden field called inbound_referral_code in a ModelForm.
My model is as follows:
class User(models.Model):
email = models.EmailField(max_length=255, blank=False, unique=True)
inbound_referral_code = models.CharField(max_length=255)
My ModelForm is currently as follows:
class UserForm(forms.ModelForm):
model = User
fields = ['email', 'inbound_referral_code']
widgets = {'inbound_referral_code': forms.HiddenInput()}
My View is:
def register(request):
if request.method == 'POST':
form = UserForm(request.POST)
[...]
else:
form = UserForm()
return render(request, 'register.html', {'form': form})
And my template is currently:
<form action="{% url 'register' %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit"/>
</form>
Two questions:
How do I assign ?refcode parameter to inbound_referral_code field?
What happens if ?refcode isn't provided?
Combining the different answers, the following solution worked:
Set the "initial" value of the form parameter, and ensure the template renders with the bound form if validation fails. The correct view function is:
def register(request):
if request.method == 'POST':
form = UserForm(request.POST)
if form.is_valid():
return redirect([...])
else:
refcode = request.GET.get('refcode')
form = UserForm(intial={'inbound_referral_code': refcode)
return render(request, 'register.html', {'form': form})
Note that the bottom return render(...) needed to be moved so that it is also called with the form from the POST request if it contains validation errors...
To assign the refcode, you need to pass it into the form, so you pass in something other than request.POST that contains it, change it before
dict = request.POST.copy()
dict["inbound_referral_code"] = request.POST.get("refcode")
form = UserForm(dict)
# ...
or after validating:
if form.is_valid():
form.cleaned_data["inbound_referral_code"] = request.POST.get("refcode")
If it isn't provided, you can check for that and pass a custom value, or set a default when defining the form/model.
To set it in the template, you can pass an initial value
else:
form = UserForm(initial={"inbound_referral_code": "ref-value-here"})
return render(request, 'register.html', {'form': form})

upload file using django form

Can anyone help me find my mistake.I am new to django.I want to upload a image using form.
#forms.py
class ProfileFormSt(forms.Form):
image_url = forms.FileField(required=False)
#views.py
class UpdateProfileStView(FormView):
template_name = "home/member_st_form.html"
def get(self, request, id):
user = User.objects.get(id=self.kwargs['id'])
profile = StudentProfile.objects.get(user=user)
form = ProfileFormSt(initial={
'image_url': profile.propic,
})
return render(request, self.template_name, {'form': form})
def post(self, request, id):
user = User.objects.get(id=self.kwargs['id'])
form = ProfileFormSt(request.POST, request.FILES)
profile = StudentProfile.objects.get(user=user)
if request.POST.get('image_url'):
profile.propic = request.POST.get('image_url')
profile.save()
return redirect('home:member-profile-st', id)
#member_st_form.html
<form action="" method="post" enctype="multipart/form-data">{% csrf_token %} {{ form.as_p }}
<button type="submit">update</button>
</form>
#models.py
class StudentProfile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
propic = models.FileField(default="profile-icon.png")
request.POST.get('image_url') always returns empty...cant find what I did wrong...
Your image_url is a file field, so it should be present in request.FILES
if request.FILES['image_url']:
profile.propic = request.FILES['image_url']

Django ImageField not rendering ClearableFileInput

Starting to beat my head against the wall...perhaps I am missing something simple.
models.py
class GFImage(models.Model):
image = models.ImageField(upload_to = 'uploads', null=True, blank=True)
views.py
def addImage(request):
errors = []
if request.method == 'POST':
form = ImageForm(request.POST, request.FILES)
if form.is_valid():
form.save()
urlRedirect = "/home"
return redirect(urlRedirect)
else:
form = ImageForm()
return render(request, "/add_image.html", {'form': form})
forms.py
class ImageForm(ModelForm):
class Meta:
model = GFImage
add_image.html
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<input type = "submit" value = "Submit">
</form>
Whatever I do, my form will not use the ClearableFileInput widget. It should default automatically, but even assigning it in the form's META will not work. What else could be blocking Django from using the clearable widget?
The ClearableFileInput will only display the clear checkbox when there's an initial file selected. Looking at your form, it looks like a a new form without initial data, so the checkbox won't be displayed.
def render(self, name, value, attrs=None):
.. snip ..
if value and hasattr(value, "url"):
template = self.template_with_initial
substitutions['initial'] = format_html(self.url_markup_template,
https://github.com/django/django/blob/5fda9c9810dfdf36b557e10d0d76775a72b0e0c6/django/forms/widgets.py#L372

Categories