How to pass data between django views - python

This questions addresses my question genearally, but I am looking for a more specific explanation.
I would like a user to update a a group of model objects, however, the queryset for these objects will need to be retrieved first. My plan is to do this in two seperate URs/views, getting the query set info from the first, then displaying the model formset to be updated next.
My first view gives a list of all the the "Project"s (One of my models), and retrieves the id of the project selected.
Here is the form:
class ProjectLookupForm(forms.Form):
Project_Name = chosenforms.ChosenModelChoiceField(queryset=Project.objects.all())
and here is the view:
def update_project_filter(request):
project_form = ProjectLookupForm(request.POST or None)
if request.method == 'POST':
if project_form.is_valid():
context = {"project_form":project_form}
# Get project here and share it with the next view.
selected_project_id = project_form.cleaned_data["Project_Name"].id
# Add a new return statement here?
# Or call update project view from here?
# Add a redirect button to html?
else:
errors = project_form.errors
context = {"errors":errors, "project_form":project_form}
else:
context = {"project_form":project_form}
return render(request, 'filter_update_project_form.html', context)
As one can see, I have included some comments brainstorming what my possibilities are. My goal is to send the selected_project_id to this next view, so that it can use that id as a model form query set.
def update_project(request):
UpdateFormset = modelformset_factory(Sample, fields=("sample_name", "extraction_date",
"project", "order", "notebook", "notebook_page"))
if request.method == 'POST':
formset = UpdateFormset(request.POST, request.FILES)
if formset.is_valid():
formset.save()
context = {"formset": formset, "project_form":project_form}
else:
errors = formset.errors
context = {"formset":formset, "errors":errors, "project_form":project_form}
else:
formset = UpdateFormset(queryset=Sample.objects.filter(project=2))
context = {"formset":formset, "project_form":project_form}
return render(request, 'update_project_form.html', context)
One can see here that I have hard coded the queryset like so:
queryset=Sample.objects.filter(project=2)
How can I set "project=" to my selected_project_id? Do I pass this info to the view as an input parameter? Or do I send it to the next URL and take it from there?

Assuming you've activated django.contrib.sessions.middleware.SessionMiddleware; you can pass data between views using request.session dictionary as follows:
def update_project_filter(request):
...
selected_project_id = project_form.cleaned_data["Project_Name"].id
request.session['selected_project_id'] = selected_project_id
...
def update_project(request):
...
selected_project_id = request.session.get('selected_project_id')
...

Related

How To Update Specific Model Field From Django View Before Saving A Form

So, How can I update some Model Fields automatic, without the user having to input the values?
In Models:
class Url(models.Model):
long_url = models.CharField("Long Url",max_length=600)
short_url = models.CharField("Short Url",max_length=7)
visits = models.IntegerField("Site Visits",null=True)
creator = models.ForeignKey(CurtItUser,on_delete=models.CASCADE,null=True)
def __str__(self):
return self.short_url
In Views:
def home(request):
"""Main Page, Random Code Gen, Appendage Of New Data To The DB"""
global res,final_url
if request.method == 'POST':
form = UrlForm(request.POST)
if form.is_valid():
res = "".join(random.choices(string.ascii_uppercase,k=7))
final_url = f"127.0.0.1:8000/link/{res}"
form.save()
redirect(...)
else:
form = UrlForm
return render(...)
Sow how can for exapmle set from my view the value of short_url to final_url ???
You can get the data you need from the form.
you need to get the specific instance first, then you can use that instance to save values from the form.
And do not forget to save!
url_instance = get_object_or_404(Url, pk=pk)
url_instance.short_url = form.cleaned_data['short_url']
url_instance.long_url = form.cleaned_data['long_url']
url_instance.visits = form.cleaned_data['visits']
url_instance.save()
You can find more detailed infromations in the Django Documentation.

Combined Returns in Python Function Based Views Django

I'm currently building a website with Django and I've gotten to a point where I need to print data on the screen(ListView) and update(UpdateView) data on the same page(template). From what I've found I cant do this easily with the Django generic views so I rewrote my view as a function-based view. This current piece of code updates what I need perfectly with some changes to the HTML.
def DocPostNewView(request, pk):
context = {}
obj = get_object_or_404(DocPost, id=pk)
form = GeeksForm(request.POST or None, instance=obj)
if form.is_valid():
form.save()
return HttpResponseRedirect("/" + id)
context["form"] = form
posts = DocPost.objects.all()
return render(request, "my_app/use_template.html", context)
... And this following piece of code lists objects perfectly with some changes to the HTML.
def DocPostNewView(request, pk):
context = {}
obj = get_object_or_404(DocPost, id=pk)
form = GeeksForm(request.POST or None, instance=obj)
if form.is_valid():
form.save()
return HttpResponseRedirect("/" + id)
context["form"] = form
posts = DocPost.objects.all()
return render(request, 'my_app/use_template.html', context={'posts': posts})
I just need to combine these and the only real difference is the return command at the bottom of both(the same) functions. HOW CAN I COMBINE THE RETURNS SO I CAN LIST DATA AND UPDATE DATA ON THE SAME PAGE???
Thanks
does this work for you ?
def DocPostNewView(request, pk=None):
posts = DocPost.objects.all()
obj = get_object_or_404(DocPost, id=pk)
form = GeeksForm(request.POST or None, instance=obj)
if form.is_valid():
form.save()
return HttpResponseRedirect("/" + id)
context = {"form":form, "posts":posts}
return render(request, "my_app/use_template.html", context)
in your templates you could use "posts" to list every post,
and your can use "form" to update that specific post,
the thing is for every update you make you will always be seeing the whole list of posts, if it is that what you want to achieve

How to store list data into the database using django?

I have django model with one field calle tag_name and with the forms i
am taking input from the user like below:
Now in the views.py i got the input from the user whatever he passed
and i have splited into the list like this:
def function_name(request):
if request.method == 'POST':
form = TagsForm(request.POST)
if form.is_valid():
# form = form.save(commit=False)
tag_name = form.data['tag_name']
split_tags = tag_name.split()
# print(split_tags)
form.save()
return redirect('index_questions')
else:
form = TagsForm()
context = {'form': form, }
return render(request, 'template.html', context)
with this i am storing data in to the table like this:
but i want to add these 2 name in to the table as seperated rows something like this:
what can i do in the views.py file or in to the model to make this happen?
A simple solution is to iterate over the tags and create an object for each
tags = tag_name.split()
for tag in tags:
Tag.objects.create(tag_name=tag)
formsets can provide a nice solution to editing/creating multiple of the same model

Django: creating a text with gaps for input

I want to create a text on my website, where the gaps, in which the user can input a word (like the c-tests for learning language) are dynamically created depending on the text that the function gets from the database (not yet implemented).
My idea was it to create a formset in which each label is different depending on a variable I give it.
Here is my views.py
def ctest(request):
c_test_tokens, gaps, tokenindexe = generate_c_test(beispieltext())
# EXAMPLE
# NOT WORKING ON POST REQUEST YET
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = CTestform(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/thanks/')
# if a GET (or any other method) we'll create a blank form
else:
ctestformset = formset_factory(CTestform, extra=len(gaps))
return render(request, 'ctest.html', {'form': ctestformset})
Here is my forms.py
class CTestform(forms.Form):
hello = forms.CharField(widget=forms.TextInput(attrs={'size': '5'}),
required=False, label='hello', label_suffix='')
Is this approach fine and how do I give the form a list with each element being the label for each gap, or should I search for an alternative?
EDIT:
Ok I tried the things on this site Variable number of inputs with Django forms possible?
My forms.py now has the function
def creategaps(self, c_test_tokens, gaps, tokenindexes):
wordsbeforegap = ''
gaps = {}
iteratorforgaps = 0
for i in (0, len(c_test_tokens)-1):
if '#GAP#' not in c_test_tokens[i]:
wordsbeforegap = wordsbeforegap + c_test_tokens[i]
else:
gaps[iteratorforgaps] = forms.CharField(widget=forms.TextInput(attrs={'size': '5'}),
required=False, label=wordsbeforegap, label_suffix='')
wordsbeforegap = ''
return type('test', (forms.BaseForm,), {'base_fields': gaps})
I tried to call the function from views.py but it doesnt create any form.
Here is the else statement in views.py
else:
form = CTestform.creategaps("test", c_test_tokens, gaps, tokenindexe)
return render(request, 'ctest.html', {'form': form})
Why doesnt it work?

django saving form field in generic or functional view

Lets say I have a form and its files are user, value, age
I am using generic or functional view... so how can I do like
def SomeView(request):
mod = MyModel()
mod.user = request.user
mod.value = form.cleaned_data["value"]
mod.save()
I think mod.value = form.cleaned_data["value"] can only be done with class based view. But how can I do this in generic or functinal view.
If you need to do it with functional views, you need to check the request.POST
def SomeView(request)
c = RequestContext(request, {})
if request.method == 'POST' :
form = YourForm(request.POST or None )
# your code here,
# redirect on success probably
else :
# create blank form
form = YourForm(None)
c[form]=form
return render_to_response("path/to/your/templet.html", c)
You can get value data from request(GET or POST) - request.GET.get('value', 'default_value') or request.POST.get('value', 'default_value')

Categories