How to access user input (POST) in different Django views - python

I have a view called "search" which stores POST input as "search_id" but "search_id" is only available in the scope of the view "search". I want to be able to access the variable "search_id" in my view "dispTable".
Disclaimer- if this part of my question makes no sense, plz ignore: I understand that I could add an additional parameter to dispTable which would allow me to pass the search_id into dispTable in a return statement but what if I wanted to be able to access search_id in multiple views.
def search(request):
if request.method == 'POST' :
search_id = request.POST.get('textfield', None)
try:
return dispTable(request)
except Person.DoesNotExist:
return HttpResponse("no such user")
except Person.MultipleObjectsReturned :
#return dispTable(request, search_id)
return showResults(request)
else :
return render(request, 'People/search.html')
def dispTable(request) :
table = authTable(Person.objects.filter(MAIN_AUTHOR = 'search_id'))
RequestConfig(request).configure(table)
#return render(request, 'People/tableTemp.html', {'table':table})
return render(request, 'People/tableTemp.html', {"table" : Person.objects.filter(MAIN_AUTHOR = search_id)})
I also tried using a form, but I still did not know how to access the input variable in additional views, like dispTable
from django import forms
class SearchForm(forms.Form) :
search_id = forms.CharField(max_length=100)
def process(self) :
search_id = self.cleaned_data['search_id']
def search(request) :
if request.method == 'POST' :
form = SearchForm(request.POST)
if form.is_valid() :
form.process()
return dispTable(request)
else :
form = SearchForm()
return render (request, 'People/search.html')
And here is my html file:
<form method="POST" action="send/">
{% csrf_token %}
<input type="text" name="textfield">
<button type="submit">Upload text</button>
</form>

Related

Django multiple forms, one form resets other form

Got some forms in my view...
I want that only what I have submitted is changed in the database. So that no forms overwrite each other. How can I do this with my view?
I even noticed that the order in which each '..._form.is_valid()' is, makes a difference in what gets overwritten
views.py
#login_required
def DashboardView(request):
browser = str(request.user_agent.browser.family)
user = str(request.user)
short_user = user[0:7] + "..."
try:
radius = request.user.fieldradius
except FieldRadius.DoesNotExist:
radius = FieldRadius(user=request.user)
try:
font_size = request.user.fontsize
except FontSize.DoesNotExist:
font_size = FontSize(user=request.user)
try:
change_color = request.user.colors
except Colors.DoesNotExist:
change_color = Colors(user=request.user)
try:
toggle_settings = request.user.togglesettings
except ToggleSettings.DoesNotExist:
toggle_settings = ToggleSettings(user=request.user)
try:
page_details = request.user.pagedetails
except PageDetails.DoesNotExist:
page_details = PageDetails(user=request.user)
if request.method == 'POST':
form = FieldForm(request.POST, instance=Field(user=request.user))
togglesettings_form = ToggleSettingsForm(
request.POST, instance=toggle_settings)
radius_form = FieldRadiusForm(request.POST, instance=radius)
change_color_form = ColorsForm(request.POST, instance=change_color)
fontsize_form = FontSizeForm(request.POST, instance=font_size)
pagedetails_form = PageDetailsForm(
request.POST, request.FILES, instance=page_details)
if togglesettings_form.is_valid():
togglesettings_form.save()
return redirect('/dashboard/#panel1')
if form.is_valid():
time.sleep(1.5)
obj = form.save(commit=False)
obj.creator_adress = get_client_ip(request)
obj.save()
return redirect('/dashboard')
if radius_form.is_valid():
radius_form.save()
return redirect('/dashboard')
if fontsize_form.is_valid():
fontsize_form.save()
return redirect('/dashboard')
if change_color_form.is_valid():
change_color_form.save()
return redirect('/dashboard')
if pagedetails_form.is_valid():
pagedetails_form.save()
return redirect('/dashboard')
else:
form = FieldForm()
radius_form = FieldRadiusForm(instance=radius)
fontsize_form = FontSizeForm(instance=font_size)
change_color_form = ColorsForm(instance=change_color)
pagedetails_form = PageDetailsForm(instance=page_details)
togglesettings_form = ToggleSettingsForm()
return render(request, 'dashboard.html', {'form': form, 'togglesettings_form': togglesettings_form, 'fontsize_form': fontsize_form, 'change_color_form': change_color_form, 'browser': browser, 'short_user': short_user, 'radius_form': radius_form, 'radius': radius, 'pagedetails_form': pagedetails_form})
If I submit a form, for example the togglesettings_form, it looks like this in the database:
After that, I submit another form, for example the fontsize_form. The fontsize_form will be saved but then the togglesettings_form will be resetted:
Forms and models, if you want to see them:
https://pastebin.com/PhaFCdBP
I have read something like
if ...form in request.POST:
do this
But I dont know how to implement that in my view
Usually I name the submit button on the form something like "my-form"
Then you can just go:
if "my-form" in request.POST:
then do what you need to do
View example:
if 'load_doc' in request.POST:
file = request.FILES['document_file']
doc = documents(client=current_client,document_name=request.POST['document_name'],document_file=file)
doc.save()
html example:
<form method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
<div class="panel-body">{{ single_load_form|crispy }}</div>
<div class="panel-footer"><button class="btn btn-primary" name="load_doc">Submit</button></form></div>

How can you use Create() and Update() in the same Django HTML page?

I am trying to create a page where I can create a new entry/note to a list and also update an existing list on one HTML page. The problem is create() does not require a primary key. However, update() requires existing primary key. How can do I do this in django? Do I create a new function in views.py? Example:
def new_note(request, note_id=None):
if note_id == None:
notes(request) #function that just uses create()
else:
note_sad(request, note_id) #sad=save and delete using update() and delete()
views.py sample function for entering notes:
def notes(request):
if request.method == 'GET':
notes = Note.objects.all().order_by('note_id')
form = NoteForm()
return render(request=request,
template_name='notes.html',
context={
'notes': notes,
'form': form
})
# when user submits form
if request.method == 'POST':
form = NoteForm(request.POST)
if form.is_valid():
note = form.cleaned_data['note']
Note.objects.create(note=note)
# "redirect" to the todo homepage
return HttpResponseRedirect(reverse('new_note'))
views.py function for creating a new entry/note:
def note_sad(request, note_id):
if request.method == 'GET':
note = Note.objects.get(pk=note_id)
form = NoteForm(initial={'note_text': note.note_text})
return render(request=request,
template_name='notes.html',
context={
'form': form,
'note_id': note_id
})
if request.method == 'POST':
if 'save' in request.POST:
form = NoteForm(request.POST)
if form.is_valid():
note = form.cleaned_data['note']
Note.objects.filter(pk=note_id).update(note_text=note)
elif 'delete' in request.POST:
Note.objects.filter(pk=note_id).delete()
return HttpResponseRedirect(reverse('new_note'))
There are many ways to pass the ID to note_sad for updating the object. One way is when you display the items on your HTML and add Id for each submit button as follows:
{% for note in notes %}
<input type='submit' value='{{note.pk}}' name='pk'>
{% end for %}
Alternatively, you may add the Id to the form as follows:
<form method = "post" action="{% url 'note_sad' note.pk %}">
{% csrf_token %}
</form>

Django url error"NoReverseMatch at /2/ipd/"

I am having form which creates Ipd and Ipd model is created using patient model with one to many relationship, and I am already having one table with patient list in urls.
I am trying to create the list of all Ipd that are created using form, I am trying to redirect the form page to Idp list after I submit for Ipd form but ending with this error "NoReverseMatch at /1/ipd/",
One thing I want to clear is each Ipd is having unique id and Ipd is created from patient with one to many relationship which also have another unique id , the number which is in the error is patient id
views.py
#login_required
def ipd(request, patient_id):
object = get_object_or_404(Patient,pk=patient_id)
if request.method == "POST":
formtwo = IpdForm(request.POST)
if formtwo.is_valid() :
instance = formtwo.save(commit=False)
instance.save()
return HttpResponseRedirect(reverse('ipd_list', args=[patient_id]))
else:
return HttpResponse(formtwo.errors)
else:
formtwo = IpdForm()
return render(request, 'newipd.html', {'object':object, 'form2': formtwo})
#login_required
def ipd_list(request):
ipdlist = Ipd.objects.all()
return render(request, 'Ipdlist.html', {'ipd': ipdlist })
urls.py
re_path(r'^$', my_patient.index, name='home'), <-- patient list-->
re_path(r'^(?P<patient_id>\d+)/ipd/$', my_patient.ipd, name='ipd'),
path(r'^ipdlist/', my_patient.ipd_list,name='ipdlist' ),
Template
<ul>
<li>Indoor Patient Department</span></li>
</ul>
########
in ipdform
<form class="col s12" role="form" action="{% url 'ipd_list' 'patient_id' %}" method="post" enctype="multipart/form-data"> {% csrf_token %}
You have to remove args=[patiend_id] since you are returning to the ipd_list
return HttpResponseRedirect(reverse('ipd_list'))
You are trying to redirect user to ipdlist url instead with patameters. As this is a list method you shouldn't do that. You need to change:
#login_required
def ipd(request, patient_id):
object = get_object_or_404(Patient,pk=patient_id)
if request.method == "POST":
formtwo = IpdForm(request.POST)
if formtwo.is_valid() :
instance = formtwo.save(commit=False)
instance.save()
return HttpResponseRedirect(reverse('ipd_list'))
else:
return HttpResponse(formtwo.errors)
else:
formtwo = IpdForm()
return render(request, 'newipd.html', {'object':object, 'form2': formtwo})
#login_required
def ipd_list(request):
ipdlist = Ipd.objects.all()
return render(request, 'Ipdlist.html', {'ipd': ipdlist })

"Didn't return an HttpResponse object. It returned None instead" on POST request

I'm trying to pass a selection from a dropdown form into views as a POST request, then using this selection to query some data from django. I'm then using these queries to try and follow this approach to map django models data to highcharts. The problem is I'm getting a "the view properties.views.property_list didn't return an HttpResponse object. It returned None instead" error when I submit the form. I've looked through similar questions on SO but none of the solutions seem to work/be applicable to my case. Perhaps my form is invalid, though I'm not sure what's causing that to be the case. Below is the code that I've written:
views.py
def property_list(request):
if request.user.is_authenticated():
current_user_groups = Group.objects.filter(id__in=request.user.groups.all())
current_user_properties = Property.objects.filter(groups__in=current_user_groups)
current_user_meters = Meter.objects.filter(meter_id__in=current_user_properties)
property_meter_data = MeterData.objects.filter(meter__in=current_user_meters)
class AccountSelectForm(forms.Form):
accounts = forms.ModelChoiceField(queryset=current_user_meters)
accounts.widget.attrs.update({'class' : 'dropdown-content'})
form = AccountSelectForm()
if request.method == "POST":
if form.is_valid():
selection = form.cleaned_data['accounts']
current_user_groups = Group.objects.filter(id__in=request.user.groups.all())
current_user_properties = Property.objects.filter(groups__in=current_user_groups)
current_user_meters = Meter.objects.filter(meter_id__in=current_user_properties)
selected_meters = Meter.objects.filter(name=selection)
selected_meter_data = MeterData.objects.filter(name=selection)
usage_data = {'usage': [], 'dates': []}
for meter in selected_meter_data:
usage_data['usage'].append(meter.usage)
usage_data['dates'].append(meter.usage)
# data passing for usage chart
usage_xAxis = {"title": {"text": 'Date'}, "categories": usage_data['dates']}
usage_yAxis = {"title": {"text": 'Usage'}, "categories": usage_data['usage']}
usage_series = [
{"data": usage_data['usage']},
]
return HttpResponseRedirect('properties/property-selected.html', {
'form': form,
'usage_xAxis': usage_xAxis,
'usage_yAxis': usage_yAxis,
'usage_series': usage_series,
'current_user_meters': current_user_meters,
'selection': selection,
'selectected_meters': selected_meters,
'selected_meter_data': selected_meter_data,
})
else:
current_user_groups = Group.objects.filter(id__in=request.user.groups.all())
current_user_properties = Property.objects.filter(groups__in=current_user_groups)
current_user_meters = Meter.objects.filter(meter_id__in=current_user_properties)
property_meter_data = MeterData.objects.filter(meter__in=current_user_meters)
return render(request, 'Properties/properties.html',{
'form': form,
'current_user_groups': current_user_groups,
'current_user_properties': current_user_properties,
'current_user_meters': current_user_meters,
'property_meter_data': property_meter_data
})
else:
# If the usre isn't authenticated, the user is redirected to the Sign-n Page
return render(request, 'SignIn/SignInPage.html')
template.html
<!-- Query based content for dropdown menu -->
<form method="POST" action="" id="property-select">
{% csrf_token %}
{{ form.accounts }}
<input type="submit" value="Submit" class="submit-button" style="margin-top:30px;"/>
</form>
If method=='POST' and your form is invalid, nothing is returned.

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})

Categories