django edit and update multiple object of one form - python

I have one form for add information to table and in craete view I can copy the form as much I want and insert it to the table like this:
My form and can copy them:
But when I want to edit and update them how can I pass the queryset to form and show them in template I write my view like this and choose formset but my formset never show in template:
def machineedit(request, id):
querymachine = machinefixedmodel.objects.get(pk=id)
querywarranty = warranty.objects.get(machine_id=id)
# querygallery = galleryModel.objects.filter(machine_id=id)
querynet = netpriod.objects.filter(machine_id=id)
newadform = modelformset_factory(netpriod, form=netpriodfrom,fields=('activity', 'material'),
extra=0)
# print(newadform)
formmachine = MachinefixedForm(instance=querymachine)
formwaranty = warrantyForm(instance = querywarranty)
# formgallery = galleryform(instance = querygallery)
# formblueprint = galleryform(instance = querygallery)
# formnetpriod = netpriodfrom(instance=querynet)
formnetpriod = newadform(request.POST or None, querynet)
context ={'formmachine': formmachine,
# 'formgallery': formgallery,
'formwarranty': formwaranty,
# 'formblueprint': formblueprint,
'formnetpriod': formnetpriod,}
return render(request, "edit.html", context)
Is the way I choose the right way or not?
can anyone help me please...

Related

How to get multiple queryset from textarea in django

I have a text area in which user inputs multiple values in different line and i want to get object for every single line in text area and send it to template. How i should do it.?
if request.method == 'GET':
search = request.GET.get('search')
slist = []
for i in range(4):
slist.append(search.splitlines()[i])
sdata = Stock.objects.all().filter(slug=slist)
return render(request, 'stocks/searchbar.html', {'sdata':sdata})
I'm trying to do it in this way.
You need to do something like this:
sdata = Stock.objects.filter(slug__in=search.splitlines())
Since search.splitlines() returns a list and slug is, I assume, a CharField, you need the in clause in your query.

How to retain the state of dropdown after performing a POST request in django

I have a page that contains three dropdowns 1. Select question type, 2. Select Marks, 3. Available Tags which are part of QuestionFilterForm. And then I have another form called QuestionPaperForm on the same page inside the <form>. When I select a question type, a list of questions is visible on the same page after a post request. And then I can select one or many from the list of new questions which is another POST request (to add these questions to another list). After the second POST request when I try to refresh the page, chrome shows an alter of form resubmission. In this case, I thought of doing redirect after POST, but then with redirect, I can't retain the options selected in the dropdown. I have to each time select options and view the list of questions. I am not able to think of a good logic where I can handle the redirect issue.
My view is as follows
def design_questionpaper(request, course_id, quiz_id, questionpaper_id=None):
context = {}
user = request.user
if quiz_id:
quiz = get_object_or_404(Quiz, pk=quiz_id)
if questionpaper_id is None:
question_paper = QuestionPaper.objects.get_or_create(
quiz_id=quiz_id
)[0]
else:
question_paper = get_object_or_404(
QuestionPaper, id=questionpaper_id, quiz_id=quiz_id
)
questions, state = None, None
marks = request.POST.get('marks', None)
state = request.POST.get('is_active', None)
question_type = request.POST.get('question_type', None)
if request.method == "POST":
filter_form = QuestionFilterForm(request.POST, user=user)
if question_type:
questions = _get_questions(user, question_type, marks)
if questions:
questions = _remove_already_present(questionpaper_id, questions)
if 'add-fixed' in request.POST:
return redirect(
'yaksh:designquestionpaper',
course_id=course_id,
quiz_id=quiz_id,
questionpaper_id=questionpaper_id
)
# question_paper.update_total_marks()
# question_paper.save()
# context['qpaper'] = question_paper
# context['questions'] = questions
else:
filter_form = QuestionFilterForm(user=user)
fixed_questions = question_paper.get_ordered_questions()
context['qpaper'] = question_paper
context['questions'] = questions
context['fixed_questions'] = fixed_questions
context['filter_form'] = filter_form
context['course_id'] = course_id
context['state'] = state
return render(request, 'yaksh/design_questionpaper.html', context)

Django data saving and presenting

My Django project need to acquire one list after processing in one function of views.py.
def acquire(request):
import sys
n = []
for topic in Topic.objects.filter(owner=request.user).order_by("date_added"):
entries = topic.entries.all()
q = entries.text
n.append(q)
return render(request, "projects/topics.html", n)
The list "n" above need to be transferred to another function of views.py for the information in another "results.html" page.
def results(request):
data = XXXX
return render(request, "projects/results.html", {"datas": data})
How could I edit "XXX" in results function to transfer the "n" list?
You can write a utility function that can be used by both views and stores the data for the current session:
def acquire(request):
data = _get_data(request)
return render(request, "projects/topics.html", {'data': data})
def results(request):
data = _get_data(request)
return render(request, "projects/results.html", {'data': data})
# this is not a view, but a utility function
def _get_data(request)
# this will try to use the data generated in a previous request of
# the same session. So the data might be stale by now
if not 'user_entries' in request.session:
n = []
for topic in Topic.objects\
.filter(owner=request.user)\
.order_by('date_added')\
.prefetch_related('entries'): # prefetch avoids the nested queries
for entry in topic.entries.all():
n.append(entry.text)
request.session['user_entries'] = n
return request.session['user_entries']
You can declare the list n outside of the function so you can use it wherever you want, like:
n = []
def acquire(request):
import sys
for topic in Topic.objects.filter(owner=request.user).order_by("date_added"):
entries = topic.entries.all()
q = entries.text
n.append(q)
return render(request, "projects/topics.html", n)
def results(request):
data = n
return render(request, "projects/results.html", {"datas": data})
You have to remember that whatever variable you set, it only lives within the view/function as Django is stateless. That's why you have a database and cookies.
This is how you do it. Unless that list has thousands and thousands of entries, this will be fast.
def results(request):
data = []
for topic in Topic.objects.filter(owner=request.user).order_by("date_added"):
entries = topic.entries.all()
q = entries.text
data.append(q)
return render(request, "projects/results.html", {"datas": data})
If you want to be really fast, you could change the request and work on the database level and create a join. Something along the lines of this (I'm a bit rusty)
data = Entries.objects.filter(topic__owner=request.user).order_by("topic__date_added").values("text")

Django Formsets: How to properly iterate over forms in a formset and save the corresponding dictionaries

I have created a formset and I know that form data is being returned as a dictionary. I thought that I could just loop over the forms in a formset and store every dictionary in another dictionary. That doesn't seem to work though, because I am only able to store the latest form (in my template I can dynamically add and remove forms). What I tried was this:
def index(request):
data = {}
data['education_data'] = {}
EducationFormSet = formset_factory(EducationForm)
if request.method == "POST":
persoform = PersonalForm(request.POST)
education_formset = EducationFormSet(request.POST)
if persoform.is_valid() and education_formset.is_valid():
data['personal_data'] = persoform.cleaned_data
entry = 1
en = 'entry_%d' % entry
for form in education_formset:
data['education_data'][en] = form.cleaned_data
entry = entry + 1
print(data)
My wanted output would be:
data = {'personal_data':{inputs}, 'education_data': { 'entry_1':{inputs}, ... 'entry_n':{inputs}}}
EDIT:
The problem was the way I tried to add keys to the "Education_Data" key. The following works:
for form in education_formset:
data['education_data']['entry_%d' % entry] = form.cleaned_data
[...]

How to save a non ModelForm form to database in Django

I'm a newbie Django user, struggling with submitting form data to the database. So that I can generate dynamic forms I am using a non-ModelForm form to capture field data.
I'm commented out validation for now but I am trying to capture the POST data from the form to the database. The latest 'draft' of my views.py code is as follows - most interested in format from form_to_save = Scenario(...):
def scenario_add(request, mode_from_url):
urlmap = {
'aviation': 'Aviation',
'maritime': 'Maritime',
'international_rail': 'International Rail',
'uk_transport_outside_london': 'UK Transport (Outside London)',
'transport_in_london': 'Transport in London',
}
target_mode = urlmap[mode_from_url]
m = Mode.objects.filter(mode=target_mode)
tl = m[0].current_tl.threat_l
scenario_form = ScenarioForm(request.POST or None, current_tl=tl, mode=target_mode)
if request.method == 'POST':
#if scenario_form.is_valid():
form_to_save = Scenario(
target = Target(descriptor = scenario_form.fields['target']),
t_type = ThreatType(t_type = scenario_form.fields['t_type']),
nra_reference = NraReference(nra_code = scenario_form.fields['nra_reference']),
subt = scenario_form.fields['subt'],
ship_t = ShipType(ship_t = scenario_form.fields['ship_t']),
likelihood = scenario_form.fields['likelihood'],
impact = scenario_form.fields['impact'],
mitigation = scenario_form.fields['mitigation'],
compliance_score = scenario_form.fields['compliance_score'],
notes = scenario_form.fields['notes']
)
form_to_save.save()
# This needs to be changed to a proper redirect or taken to
# a scenario summary page (which doesn't yet exit.)
return render(request, "ram/new_scenario_redirect.html", {
'scenario_form': scenario_form,
'mode': mode_from_url,
'mode_proper': target_mode
})
else:
# if there is no completed form then user is presented with a blank
# form
return render(request, 'ram/scenario_add.html', {
'scenario_form': scenario_form,
'current_tl': tl,
'mode': mode_from_url,
'mode_proper': target_mode
})
Any advice gratefully received. Many thanks.
You've commented out the is_valid check, for some reason. You need that: as well as checking for validity, it also populates the form's cleaned_data dictionary which is what you should be getting the data from to create your object. (And don't call that object "form_to_save": it's a model instance, not a form).
if request.method == 'POST':
if scenario_form.is_valid():
scenario = Scenario(
target = Target(descriptor=scenario_form.cleaned_data['target']),
t_type = ThreatType(t_type = scenario_form.cleaned_data['t_type'])
...etc
Plus, you should move the final "return render" call out of the else block, so that it is caught when the form is not valid, to show any errors.
However, as petkostas says, you would almost certainly be better off using an actual ModelForm in the first place.
You can add custom options by overriding the init function in your form. For example:
class SomeForm(forms.Form):
department = forms.ChoiceField(widget=forms.Select, required=True)
...
def __init__(self, *args, **kwargs):
super(SomeForm, self).__init__(*args, **kwargs)
self.fields['department'].choices = Department.objects.all().order_by('department_name).values_list('pk', 'department_name')
You can also change the queryset in the init function:
where Department is a foreign key for example
queryset = Department.objects.filter(your logic)
self.fields['department'].queryset = queryset

Categories