I have an app project. I am able to save instances to the model in the database no problem. But I cannot pull in the instance by pk to the html form to edit and update. please see setup below can anyone provide any guidence or help, as to why this is not happening and how I can resolve?
views.py
def edit_properties(request, id):
properties = Properties.objects.get(pk=id)
context = {
'properties': properties,
'values': properties,
}
if request.method == 'GET':
return render(request, 'sub/edit_properties.html', context)
you better use ModelForm to update data in your models
class PropertiesEditForm(forms.ModelForm):
class Meta:
model = Properties
then you need to update your view to use this form
def edit_properties(request, id=None):
properties = Properties.objects.get(pk=id) if id else None
form = PropertiesEditForm(request.POST or None, instance=properties)
if request.POST:
if form.is_valid():
form.save()
return HttpResponseRedirect("url_to_show_your_new_data")
context = {
'form': form,
}
return render(request, 'sub/edit_properties.html', context)
and in html file you use this form
<form method="POST" action="URL_TO_EDIT_PROPERTIES_VIEW">{% csrf_token %}
{{ form }}
<input type="submit"/>
</form>
Found the issue, in my html the "{{values.address1}}" should be "{{values.Address1}}" as the attribute in the database is capital first letter.
Little less stressed now :)
<div class="form-row my-3">
<div class="form-group col-md-6">
<label for="Addressline1">Address line 1</label>
<input type="text" class="form-control" name="address1" id="address1Field"
value="{{values.address1}}">
</div>
Thank you all for your help,
Related
This method works fine for me can some one say how to add file or images like this
def insert_students(request);
name = request.POST['name']
class = request.POST['class']
student = studentsmodels(name=name, class=class)
student.save()
return redirect('/')
return render(request, "insertpage.html")
Using Django forms would make your life so much easier, frankly. However, you can still create objects without forms and add files to them. Instead of request.POST the files are stored in request.FILES the documentation goes into detail about how files are uploaded:
https://docs.djangoproject.com/en/4.0/topics/http/file-uploads/
def submit_form(request):
if request.method == POST:
name = request.POST["name"]
class = request.POST["class"]
if Mymodel.objects.filter(name=name, class=class).exist():
messages.infor("class and name already exist")
else:
MyModel.objects.create(name=name, class=class)
return render(request, "submit_form.html)
submit_form.html
<form action="{% url 'submit_form' %}" method="post">
{%csrf_token%}
<input name="name" placeholder="Enter Name" type="text">
<input name="class" type="text" placeholder="Enter Class">
<button class="button is-success is-fullwidth is-medium mt-5"
type="submit">submit
</button>
</form>
Tags will not store in database in Django
def addque(request):
if request.method == "POST":
user = request.user
if user.is_anonymous:
return redirect('addquery')
if user.is_active:
question = request.POST['question']
body = request.POST['body']
tags = request.POST['tags']
aquuid = request.user.aquuid
addquery = Question(question=question, user_id=aquuid, que_body=body, tags=tags)
addquery.save()
return redirect('addquery')
else:
return render(request, 'question/ask.html')
After giving the input the data is stored in the tags field but, not saving in the database. I can manually insert data through the admin panel successfully but not as a non-staff user. I have installed taggit and placed it in the installed_apps in settings.py. What is the issue with the code?
Tags are Many-to-Many objects and you can't add those to an object until the object has been saved. The documentation shows that you need to use .add() to add tags to a model instance. Your code should be:
addquery = Question(question=question, user_id=aquuid, que_body=body)
addquery.save()
addquery.tags.add(tags)
As an aside, you might be better served by a ModelForm which can handle the tags and all of this stuff that you're doing:
question = request.POST['question']
body = request.POST['body']
tags = request.POST['tags']
https://django-taggit.readthedocs.io/en/latest/forms.html
Use model form
In html use id of forms like this
HTML
<form action="{% url 'addquery' %}" method="post">
{% csrf_token %}
<div class="psrelative">
<input id="id_question" name="question" type="text" maxlength="300" tabindex="100" placeholder="e.g. Is there an R function for finding the index of an element in a vector?" class="s-input js-post-title-field" value="" data-min-length="15" data-max-length="150" autocomplete="off" required>
</div>
<textarea name="que_body" id="id_que_body" class="textarea-body"></textarea required>
<div class="psrelative">
<input id="id_tags" name="tags" type="text" maxlength="300" tabindex="100"
placeholder="e.g. (ruby-on-rails vba spring)" class="s-input js-post-title-field" value="" data-min-length="15" data-max-length="150" autocomplete="off" required>
</div>
<button class="review-question-btn" type="submit" tabindex="120"> Submit your question
</button>
</form>
Forms.py
from django import forms
from .models import Question
class Addqueform(forms.ModelForm):
class Meta:
model = Question
fields = ['question','que_body','tags']
Views.py
from .forms import Addqueform
def addque(request):
queform = Addqueform(request.POST)
if request.method == "POST":
user = request.user
if user.is_anonymous:
return redirect('addquery')
if user.is_active:
if queform.is_valid():
aquuid = request.user.aquuid
question = queform.cleaned_data['question']
body = queform.cleaned_data['que_body']
tags = queform.cleaned_data['tags']
addquery = Question(question=question, user_id=aquuid, que_body=body)
for tag in tags:
addquery.tags.add(tag)
addquery.save()
return redirect('addquery')
else:
queform = Addqueform()
return render(request, 'question/ask.html', {'form': queform})
else:
return render(request, 'question/ask.html', {'form': queform})
I think It will Work
I'm using the below custom form in my Django app:
forms.py
class UpdateURLForm(forms.ModelForm):
VideoURL = forms.URLField()
MainDescription = forms.CharField(max_length=100)
class Meta:
model = Listing
fields = ('VideoURL', 'MainDescription',)
Then, in views.py I import the form and then I render the fields into my HTML template:
def edit_info(request):
if request.method == 'POST':
form = UpdateURLForm(request.POST)
if form.is_valid():
VideoURL = form.cleaned_data['VideoURL']
MainDescription = form.cleaned_data['MainDescription']
else:
form = UpdateURLForm()
return render(request, 'myapp/updateinfo.html', {'form': form})
HTML:
<form action="#" method='post' class="card shadow-soft border p-4 mb-4">{% csrf_token %}
<div class="form-group">
<label for="video">Video URL:</label>
{{form.VideoURL|add_class:"form-control shadow-soft"}}
</div>
<div class="form-group">
<label for="video">Video URL:</label>
{{form.MainDescription|add_class:"form-control shadow-soft"}}
</div>
<div class="row">
<div class="col">
<button class="btn btn-primary btn-dark mt-2 animate-up-2 text-right"
type="submit">Update</button>
</div>
</div>
</form>
Now, my question is: how can I render the field MainDescription in the template in order to save both information into the database? The way I rendered the second field (MainDescription) doesn't work. Thanks!
Edit
So, I have two fields in my custom form which (VideoURL and MainDescription) which I would like to use to update some info in the DB. When I try to render in the HTML template both are getting the same ID whereas I was expecting that each field of the form to be rendered:
<input type="text" name="VideoURL" value="https://videourl.com" maxlength="100" class="form-control shadow-soft" required="" id="id_VideoURL">
I do not figure out what I am missing.
Every ModelForm has a save() method. This method creates and saves a database object from the data bound to the form. A subclass of ModelForm can accept an existing model instance as the keyword argument instance; if this is supplied, save() will update that instance. If it’s not supplied, save() will create a new instance of the specified model:
EXAMPLE 1 with forms.ModelForm
forms.py
class UpdateURLForm(forms.ModelForm):
class Meta:
model = Listing
fields = ['video_url', 'main_description']
So you can ease save your form.
views.py
def edit_info(request):
if request.method == 'POST':
form = UpdateURLForm(request.POST)
if form.is_valid():
instance = form.save()
else:
form = UpdateURLForm()
return render(request, 'myapp/updateinfo.html', {'form': form})
EXAMPLE 2 with forms.Form
forms.py
class UpdateURLForm(forms.Form):
video_url = forms.URLField(label="Video Url")
main_description = forms.CharField(label="Description", max_length=100)
You can also import your model and create an object.
views.py
from models import Listing
def edit_info(request):
if request.method == 'POST':
form = UpdateURLForm(request.POST)
if form.is_valid():
listing = Listing(video_url=form.cleaned_data.get('video_url'), main_description=form.cleaned_data.get('main_description'))
listing.save()
else:
form = UpdateURLForm()
return render(request, 'myapp/updateinfo.html', {'form': form})
I am trying to create an 'add user' feature which will simply add the user you've selected from a dropdown as your connection. I am using ModelChoiceField from Django Forms so that I may get the existing users from my User model in the dropdown.
forms.py
from django import forms
from django.contrib.auth.models import User
class NetworkForm(forms.Form):
user_id = forms.ModelChoiceField(queryset=User.objects.all(), label='',
widget=forms.Select(attrs={'class': 'all_users'}))
views.py
#login_required
def index(request):
user_list = User.objects.exclude(username=request.user)
return render(request, 'chat/index.html', {'user_list': user_list})
For now I am just printing the form to see output
#login_required
def add_user(request):
form = NetworkForm()
if request.method == 'POST':
form = NetworkForm(request.POST)
if form.is_valid():
print form
return redirect(request.META['HTTP_REFERER'])
errors = form.errors or None
return render(request, 'chat/index.html', {
'form': form,
'errors': errors,
})
index.html
<div class="row">
<form action="{% url 'chat:add_user' %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-warning" value="{{ user_id }}" style="float: left;">Submit</button>
</form>
</div>
urls.py
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^add_user/$', views.add_user, name='add_user'),]
The way it is being rendered currently is: I have my main index page where I don't see any dropdown, i.e.,
When I click on the submit button, it moves me to index/add_user, where I get a dropdown with user (with a warning "this field is required) and a submit button again.
Finally, when I choose a user in this new page and hit submit, finally the form is printed, which I want ultimately.
What I would want it, have the complete form with dropdown in the index page itself and remain there when I submit the form. I will then hook that to show user the users they have added beneath that form itself ('print' is just for debugging purpose - not a good way I've heard though).
I understand the post request will have to go to add_user page and I can redirect back from that. I have tried various alternatives for the past 6 hours, nothing works yet. Apologies for a long one, giving out information as much as possible. Thanks very much guys. You are awesome.
Edit
Have been now rendering the form in index page (suggestion from #fazil-zaid ), but the issue remains as in only 'submit' button appears on index initially, unless when I hit submit after which the dropdown and submit appears. Again, on clicking the second time, the form is submitted.
Edit-2
I am thinking that:
<form action="{% url 'chat:index' %}" method="post">{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-warning" value="{{ user_id }}" style="float: left;">Submit</button>
</form>
this might be where the problem is, as per current logic unless user takes form's action, i.e., clicks the button {{ form.as_p }} will not appear. Then I tried:
{{ form.as_p }}
<form action="{% url 'chat:index' %}" method="post">{% csrf_token %}
<button class="btn btn-warning" value="{{ user_id }}" style="float: left;">Submit</button>
</form>
Doesn't work still. POST request doesn't send any data (understandably so).
If you want the form to be in the index page, then you could include it in the index view itself.
def index(request):
if request.method == 'POST':
form = NetworkForm(request.POST)
if form.is_valid():
#do what you wanna do
#with the form data.
else:
form = NetworkForm()
render(request, 'chat/index.html', { 'form': form})
In the template,
<div class="row">
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-warning" value="{{ user_id }}" style="float: left;">Submit</button>
</form>
</div>
You are not rendering another template, but the same 'index.html'. Then, multiple view for that is just redundant. Index page could contain the form and render itself. From what I understand, there's no need of redirections.
There's no need of add_user view if you're showing the form in the index page itself.
For your issue, try changing the "class" attribute of the form fields, maybe something like this,
class NetworkForm(forms.Form):
user_id = forms.ModelChoiceField(queryset=User.objects.all(), widget=forms.Select(attrs={'class': 'form-control'}))
Solution:
When the page is called in the first instance using GET, the form is not valid as it seeks a POST method. Hence, all the method need to be changed to POST in the view, i.e.,
#login_required
def index(request):
user_list = User.objects.exclude(username=request.user)
form = NetworkForm()
if request.method == 'POST':
form = NetworkForm(request.POST)
if form.is_valid():
print form.data
return redirect(request.META['HTTP_REFERER'])
return render(request, 'chat/index.html', {
'user_list': user_list,
'form': form,
})
Earlier, index was using a GET to render data to index page, and using a POST to use the form. Now, everything works fine.
Special shout-out to #fazil-zaid for the heads-up since you mentioned to include everything in the index view itself, rather than making a separate view for form. Your code pointed that out in a way in addition to Stack here.
I am trying a basic example in uploading a file with django.
I tried the code from the django documentaion but I keep getting invalid form. And when I don't test the validation of the form and try to handle the file directly, I get:
MultiValueDictKeyError at /neurons/nblast
"
'file'"
P.S:
Previously, I had used a model with a FileField and set the (upload_to), but in my current case I don't need to use the model, I only need to let the user uploads his files.
This is my code:
Template
<body>
<form action="" method="post">
{{ form }}
<br>
<button class="btn btn-success" name="btn_upload">
<span class="glyphicon glyphicon-upload"></span>
<b>Upload</b>
</button>
{% csrf_token %}
</form>
</body>
Views
def test(request):
if request.method == GET:
form = UploadFileForm()
if request.method == POST:
if 'btn_upload' in request.POST:
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['file'])
else:
print 'Not Valid'
form = UploadFileForm()
return render_to_response('test.html',
{'form': form},
context_instance=RequestContext(request))
Forms:
class UploadFileForm(forms.Form):
file = forms.FileField()
Thank you very much
Have you tried looking at The Django 'File Uploads' docs , especially the enctype="multipart/form-data" attribute?
u missed this one enctype="multipart/form-data"