django hidden field error - django

i'm building a message system for a virtual community, but i can't take the userprofile id
i have in views.py
def save_message(request):
if request.method == 'POST':
form = MessageForm(request.POST)
if form.is_valid():
new_obj = form.save(commit=False)
new_obj.sender = request.user
u = UserProfile.objects.get(request.POST['userprofile_id'])
new_obj.owner = u
new_obj.save()
return HttpResponseRedirect('.')
else:
form = MessageForm()
return render_to_response('messages/messages.html', {
'form': form,
},
context_instance=RequestContext(request))
and the template:
{% block primary %}
<form action="." method="post">
{{ form.as_p }}
<p><input type="hidden" value="{{ userprofile.id }}" name = "owner" /></p>
<p><input type="submit" value="Send Message!" /></p>
</form>
{% endblock %}
forms.py:
class MessageForm(ModelForm):
class Meta:
model = Messages
fields = ['message']
models.py:
class Messages(models.Model):
message = models.CharField(max_length = 300)
read = models.BooleanField(default=False)
owner = models.ForeignKey(UserProfile)
sender = models.ForeignKey(User)
I don't figure out why i get this error,since i'm just trying to get the profileId of a user, using a hiddeen field.
the error is:
Key 'UserProfile_id' not found in <QueryDict: {u'owner': [u''], u'message': [u'fdghjkl']}>
and i'm getting it after i fill out the message text field.
Thanks!

it should be
u = UserProfile.objects.get(request.POST['owner'])
because the input's name is 'owner!!

Can you set raise(raise Exception,request.POST) before string: u = UserProfile.objects.get(request.POST['userprofile_id'])
And show me output.

Related

Django Form Initial Value not Showing

I want to make a form to edit a model object, with the initial data being the original data (before the change), but it doesn't show,
it was just a blank form
models.py:
class Employee(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
forms.py:
class EmployeeForm(forms.ModelForm):
class Meta:
model = Employee
fields = ['first_name', 'last_name']
labels = {'first_name' : 'First Name:', 'last_name' : 'Last Name:' }
input_attrs = {'class' : 'form-control'}
widgets = {
'first_name' : forms.TextInput(attrs=input_attrs),
'last_name' : forms.TextInput(attrs=input_attrs)}
views.py:
def edit(request, id):
employee = Employee.objects.get(id=id)
data = {
'first_name' : employee.first_name,
'last_name' : employee.last_name,
}
form = EmployeeForm(request.POST or None, initial=data, instance=employee)
if (form.is_valid and request.method == 'POST'):
form.save()
return HttpResponseRedirect('/form/')
response = {'employee_form' : EmployeeForm, 'employee':employee}
return render(request, 'editemployee.html', response)
editemployee.html:
<div class="form">
<div class="form-group">
<form action="" method="POST">
{% csrf_token %}
{% for form in employee_form %}
{{ form.label }}
{{ form }}
<br>
{% endfor %}
<input type="submit" value="Submit" class="btn btn-primary">
</form>
</div>
</div>
Can anyone please tell me where I went wrong? I've tried so many things but to no avail. The form works fine, but the initial data doesn't show.
Editing an existing record, no initial data is needed, it comes from the model instance.
form = EmployeeForm(request.POST or None, instance=employee)
If you need default data in those fields, you can add it in the model.

Why isn't this creating the models in batch?

I am trying to create the object blank in a batch but it is only creating one object after I fill in the form, could anyone help me with what I am doing wrong?
html
{% block content %}
<form class="box" method = "post">
{% csrf_token %}
<h1>Air Ticket Sales</h1>
{{ form }}
batch size:
<input type="number" name="batch" value="{{ batch }}">
<input type="submit" name="" value="Create Blank">
</form>
{% endblock %}
model
class blank(models.Model):
#an integer field that automatically increments by itself as the object are created
number = models.AutoField(primary_key=True)
type = models.CharField(max_length=50, choices=type_choices, default='green')
is_sold = models.BooleanField(default=False)
is_refunded = models.BooleanField(default=False)
date = models.DateField(auto_now_add=True)
date.editable = True
advisor = models.ForeignKey(
User,
models.SET_NULL,
blank=True,
null=True,
)
view
def create_blanks(request):
if request.method == 'POST':
#initializes the data from the form to the value form
form = blank_form(data=request.POST)
batch = request.POST.get("batch", "")
if form.is_valid():
for b in batch:
form.save()
return render(request, "create_blanks.html")
else:
return render(request, "create_blanks.html")
else:
form = blank_form
return render(request, "create_blanks.html", {'form':form})
Yep just found the solution with your help I don't think it is the most efficient or the cleanest one but here you go
for b in range(int(batch)):
form.save()
form.instance = None
form = blank_form(data=request.POST)

Saving image fails without error in django model form

I want to try to save an image to my model:
def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
return 'user_{0}/{1}'.format(instance.user.id, filename)
class Leverandor(models.Model):
ID = models.AutoField(primary_key=True)
UserID = models.ForeignKey('Stamdata', on_delete=models.CASCADE)
Name = models.CharField('Name', max_length=200)
URL = models.URLField('URL', max_length=200)
ImageURL = models.ImageField('ImageURL',blank=True, null=True, upload_to=user_directory_path)
To this Form.py:
class EditLeverandorForm(forms.ModelForm):
Name = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'autofocus': True}))
URL = forms.URLField(widget=forms.TextInput(attrs={'class': 'form-control', 'autofocus': True}))
ImageURL = forms.ImageField
class Meta:
model = Leverandor
labels = {
'Name' : 'Leverandør',
'URL' : 'Webside',
'ImageURL' : 'Logo',
}
fields = ['UserID', 'Name', 'URL', 'ImageURL']
And rendererd to this view.py
def add_leverandorer(request):
user_id = request.user.id
# if this is a POST request we need to process the form data
if request.method == 'POST':
print (user_id)
form = EditLeverandorForm(request.POST, request.FILES, instance=request.user)
if form.is_valid():
form.save()
return HttpResponseRedirect('/backend/leverandorer')
else:
print ('somethin goes wrong')
print (user_id)
form = EditLeverandorForm()
return render(
request,
'backend/add_leverandorer.html',
{
'title':'WestcoastShop - Backend',
'form': form,
}
)
The problem is that before I add the instance=request.user part its saves the entry correct but without image. Now I add the part from Django documentation like provided for save to an variable path but nothing happened after i click to save button.
<form action="/backend/leverandorer/add" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<label for="simpleinput">Leverandør</label>
{{ form.Name }}
</div>
<div class="form-group">
<label for="simpleinput">Webside</label>
{{ form.URL }}
</div>
<div class="form-group">
<label for="simpleinput">Logo</label>
{{ form.ImageURL }}
<!--<input type="file" name="ImageURL" accept="image/*" required="" id="id_ImageURL" class="form-control-file">-->
</div>
<input type="hidden" id="UserID" name="UserID" value="{{ user.id }}">
<button type="submit" class="btn btn-primary">Gem</button>
</form>
I didnt see an error but now its not saving the form in models also if ImageField is empty.
regards
Christopher.
You are using UserID as a hidden field. The hidden field will not pass the form-validation. So your following code will be false.
if form.is_valid():
form.save()
return HttpResponseRedirect('/backend/leverandorer')
One of the solutions is, remove the UserID field from your template and update your view as follows.
if form.is_valid():
user_form = form.save(commit=False)
user_form.UserID = request.user
user_form.save()
I I change the function in models.py to:
def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
return 'user_{0}/{1}'.format(instance.UserID, filename)
class Leverandor(models.Model):
ID = models.AutoField(primary_key=True)
UserID = models.ForeignKey('Stamdata', on_delete=models.CASCADE)
Name = models.CharField('Name', max_length=200)
URL = models.URLField('URL', max_length=200)
ImageURL = models.ImageField('ImageURL',blank=True, null=True, upload_to=user_directory_path)
its works, but the Path is Username and not user.id

'PersonForm' object has no attribute 'as_widget'

I am trying to pass string to a hidden field scenario of a form whose data is stored in a database. The goal is to be able to retrieve extra information on client side without having it as another field of the form.
I am getting 'PersonForm' object has no attribute 'as_widget' error.
This is my Model:
class Person(models.Model):
region = models.CharField(max_length=30)
industry = models.CharField(max_length=30)
uuid = models.CharField(max_length=50, blank=True, unique=True, default=uuid.uuid4)
scenario = models.ForeignKey(Scenario, on_delete=models.CASCADE,)
def __str__(self):
return "{}".format(self.uuid)
My Form
class PersonForm(forms.ModelForm):
class Meta:
model=Person
scenario = forms.CharField(widget=forms.HiddenInput())
fields = ['industry', 'region','scenario']
My View
def personforms(request):
persons = Person.objects.all()
if request.method == 'POST':
filled_form = PersonForm(request.POST)
if filled_form.is_valid():
created_person = filled_form.save()
#DEBUG
print(filled_form.cleaned_data['scenario'])
created_person_pk = created_person.id
filled_form = PersonForm()
return redirect('/scenariopage', {'persons':persons})
else:
created_person_pk = None
return render(request, 'core/scenario-landing-page.html', {'personform':filled_form, 'created_person_pk':created_person_pk})
else:
form = PersonForm()
return render(request, 'core/scenario-landing-page.html', {'personform':form})
And my template
<form action="{% url 'personform' %}" method="post" class="custom-form">
{% csrf_token %}
{% render_field personform class="form-control" %}
{% render_field personform.scenario class="form-control form-control-sm" value='{{ scenario.name }}' %}
<input type="submit" class="btn color-btn" value="Go to Scenario page" data-dismiss="gallery-item"/>
</form>
Questions I have:
I have no Error message. But debug print is indicating that filled_form.is_valid(): seems to be invalid.
And this line in the View never print result:
#DEBUG
print(filled_form.cleaned_data['scenario'])
What I am doing wrong?
How could I possibly pass the data to the field scenario.

Handle multiple modelforms in one html form

A user will have photos which will be related with their specific album.
So this was the model for that:
class Album(models.Model):
user = models.ForeignKey(User)
title = models.CharField(max_length=200)
pub_date = models.DateTimeField(auto_now_add=True, auto_now=False)
update = models.DateTimeField(auto_now_add=False, auto_now=True)
class Photo(models.Model):
photo_privacy = models.CharField(max_length=1,choices=PRIVACY, default='F')
user = models.ForeignKey(User)
caption = models.TextField()
image = models.ImageField(upload_to=get_upload_file_name)
pub_date = models.DateTimeField(auto_now_add=True, auto_now=False)
Views.py:
def create_album(request, user_name):
user = User.objects.get(username=unquote(user_name))
if request.method=='POST':
pform = AlbumPhotoForm(request.POST, request.FILES)
aform = AlbumForm(request.POST)
p_valid = pform.is_valid()
a_valid = aform.is_valid()
if p_valid and a_valid:
photo = pform.save(commit=False)
album = aform.save(commit=False)
photo.user = user
album.user = user
album.save()
photo.album = album
photo.save()
return HttpResponseRedirect('/'+user.username+'/photos')
else:
return render(request, 'create_album.html',{
'pform':pform,
'aform':aform
})
else:
pform = AlbumPhotoForm()
aform = AlbumForm()
return render(request, 'create_album.html', {
'pform':pform,
'aform':aform
})
And the form:
<form action="/{{ user.username }}/create_album/" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ aform.as_p }}
{{ pform.as_p }}
<input type="submit" value="Create and Upload Album"/>
</form>
This works fine if I only have to upload one file (photo) with that form.
Update:
However what I want to do is, show minimum of three input for uploading photos to the new album:
<form action="/{{ user.username }}/create_album/" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ aform.as_p }}
{{ pform.as_p }}
{{ pform.as_p }}
{{ pform.as_p }}
<input type="submit" value="Create and Upload Album"/>
</form>
When doing so, only the last pform is gets saved. And the other two pform's are ignored. How do I get to save all the three forms of photo (pform) accordingly?
Or is there any other way around? Your help will be much appreciated! Thank you.
Use formsets. They do exactly what you want:
from django.forms.models import formset_factory
PhotoFormSet = formset_factory(AlbumPhotoForm, can_delete=False,
min_num=1, validate_min=True,
max_num=3, validate_max=True,
extra=3)
def create_album(request, user_name):
user = User.objects.get(username=unquote(user_name))
if request.method=='POST':
form = AlbumForm(request.POST)
formset = PhotoFormSet(request.POST, request.FILES)
if all([form.is_valid(), formset.is_valid()]):
album = form.save(commit=False)
album.user = user
album.save()
for photo_form in formset:
if photo_form.cleaned_data:
photo = photo_form.save(commit=False)
photo.album = album
photo.user = user
photo.save()
return redirect('/%s/photos' % user.username )
else:
form = AlbumForm()
formset = PhotoFormSet()
return render(request, 'create_album.html',
{'form': form, 'formset': formset})
And template may look like this:
<form action="." method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<table>
{{ formset }}
</table>
<input type="submit" value="Create and Upload Album"/>
</form>