In View 1's form their is a field called 'reference'. I need to access whatever value is submitted in that field in View 2 and set a variable equal to it. Right now I am just getting an error "orders matching query does not exist".
This is what I'm trying (I've commented the code in view2 to indicate where im getting the error).
views.py
def view1(request, pk):
item = get_object_or_404(Manifests, pk=pk)
if request.method == "POST":
form = CreateManifestForm(request.POST, instance=item)
if form.is_valid():
form.save()
return redirect('view2')
else:
form = CreateManifestForm(instance=item)
return render(request, 'edit_manifest_frombrowse.html', {'form': form})
def view2(request):
form = CreateManifestForm(request.POST)
if request.method == "POST":
if form.is_valid():
form.save()
...
reference_id = request.POST.get('reference') #this is how Im trying to get reference from the previos view
data = Manifests.objects.all().filter(reference__reference=reference_id)
form = CreateManifestForm(initial={
'reference': Orders.objects.get(reference=reference_id), #this is where im getting "does not exist"
})
total_cases = Manifests.objects.filter(reference__reference=reference_id).aggregate(Sum('cases'))
context = {
'reference_id': reference_id,
'form': form,
'data': data,
'total_cases': total_cases['cases__sum'],
}
return render(request, 'manifest_readonly.html', context)
forms.py
class CreateManifestForm(forms.ModelForm):
class Meta:
model = Manifests
fields = ('reference', 'cases', 'product_name', 'count', 'CNF', 'FOB')
I just want to be able to use whatever value is submitted in the 'reference' field in view1 in view2 and assign it equal to reference_id
Something like this:
from django.urls import reverse
def view1(request, pk):
item = get_object_or_404(Manifests, pk=pk)
if request.method == "POST":
form = CreateManifestForm(request.POST, instance=item)
if form.is_valid():
obj = form.save()
reference_id = request.POST.get('reference') or obj.reference.id
return redirect(reverse('view2')+f'?reference={reference_id}')
else:
form = CreateManifestForm(instance=item)
return render(request, 'edit_manifest_frombrowse.html', {'form': form})
def view2(request):
if request.method == "POST":
form = CreateManifestForm(request.POST)
if form.is_valid():
form.save()
...
data = getattr(request, 'POST', None) or getattr(request, 'GET', {})
reference_id = data.get('reference') #this is how Im trying to get reference from the previos view
data = Manifests.objects.all().filter(reference__reference=reference_id)
form = CreateManifestForm(initial={
'reference': Orders.objects.get(reference=reference_id), #this is where im getting "does not exist"
})
total_cases = Manifests.objects.filter(reference__reference=reference_id).aggregate(Sum('cases'))
context = {
'reference_id': reference_id,
'form': form,
'data': data,
'total_cases': total_cases['cases__sum'],
}
return render(request, 'manifest_readonly.html', context)
Related
How can I solve this in Django?
UnboundLocalError at / local variable 'form' referenced before assignment.
def home(request):
if request.user.is_authenticated:
form = MeepForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
meep = form.save(commit=False)
meep.user = request.user
meep.save()
messages.success(request,('Meep has been posted'))
return redirect('home')
meeps = Meep.objects.all().order_by("-created_at")
return render(request, 'home/home.html', {'meeps':meeps,'form':form})
else:
meeps = Meep.objects.all().order_by("-created_at")
return render(request, 'home/home.html', {'meeps':meeps,'form':form})
Just use logic that is written similar to Django MVP views - you can just initialize the form before and then override it when it's needed with POST data.
def home(request):
form = MeepForm()
if request.user.is_authenticated:
if request.method == 'POST':
form = MeepForm(request.POST or None)
if form.is_valid():
meep = form.save(commit=False)
meep.user = request.user
meep.save()
messages.success(request, 'Meep has been posted')
return redirect('home')
meeps = Meep.objects.all().order_by("-created_at")
return render(request, 'home/home.html', {'meeps': meeps,'form': form})
The error is because of the form variable that is being referenced before it is assigned a value. In the case where the user is not authenticated, the form variable is not defined, and so you get the UnboundLocalError, try this:
def home(request):
if request.user.is_authenticated:
if request.method == 'POST':
form = MeepForm(request.POST)
if form.is_valid():
meep = form.save(commit=False)
meep.user = request.user
meep.save()
messages.success(request, 'Meep has been posted')
return redirect('home')
else:
return redirect("some_error_page")
form = MeepForm()
meeps = Meep.objects.all().order_by("-created_at")
return render(request, 'home/home.html', {'meeps': meeps,'form': form})
If your code goes into else, then you wouldn't have initialized a form object and hence the error.
else:
meeps = Meep.objects.all().order_by("-created_at")
return render(request, 'home/home.html', {'meeps':meeps,'form':form})
Here u wouldn't be having form. So initialize it here - inside else or have some value before if.
Hey so I have this list of campaigns that have a button to start and stop the process.
'''
from django.shortcuts import render
from .models import Campaign
from .forms import CampaignForm, CampaignStatusFormSet
def home_view(request):
queryset = Campaign.objects.all()
if request.method == 'POST':
form_type = request.POST.get('id')
if form_type == 'campaign_status':
formset = CampaignStatusFormSet(
request.POST, request.FILES,
queryset=queryset,
)
for form in formset.forms:
if form.is_valid():
form.save()
else:
formset = CampaignStatusFormSet(queryset=queryset)
campaigns_and_forms = list(zip(queryset, formset))
context = {
'formset': formset,
'campaigns_and_forms': campaigns_and_forms,
}
return render(request, 'campaigns_in_progress.html', context)
'''
But when I run it and click on the button to change play/pause it shows this error.
UnboundLocalError: local variable 'formset' referenced before assignment
Can anyone help me refactor this code so that it doesn't show this error?
You can remove the else block so that the formset is available even after clicking on the play/pause buttons. When you send a POST request, and campaign_status is as expected, formset variable is not available in the conext and hence the error.
from django.shortcuts import render
from .models import Campaign
from .forms import CampaignForm, CampaignStatusFormSet
def home_view(request):
queryset = Campaign.objects.all()
if request.method == 'POST':
form_type = request.POST.get('id')
if form_type == 'campaign_status':
formset = CampaignStatusFormSet(
request.POST, request.FILES,
queryset=queryset,
)
for form in formset.forms:
if form.is_valid():
form.save()
# Set form with new created campaign
queryset = Campaign.objects.all()
formset = CampaignStatusFormSet(queryset=queryset)
campaigns_and_forms = list(zip(queryset, formset))
context = {
'formset': formset,
'campaigns_and_forms': campaigns_and_forms,
}
else:
formset = CampaignStatusFormSet(queryset=queryset)
campaigns_and_forms = list(zip(queryset, formset))
context = {
'formset': formset,
'campaigns_and_forms': campaigns_and_forms,
}
return render(request, 'campaigns_in_progress.html', context)
I don't know if this is the right solution and if it won't break something else but for now it works perfectly. I just declared the formset before the if statement so it kind of declares 2 times.
If anyone could tell me if this is a good solution I would be greatful
'''
def home_view(request):
queryset = Campaign.objects.all()
formset = CampaignStatusFormSet(
request.POST, request.FILES,
queryset=queryset,
)
if request.method == 'POST':
form_type = request.POST.get('id')
if form_type == 'campaign_status':
formset = CampaignStatusFormSet(
request.POST, request.FILES,
queryset=queryset,
)
for form in formset.forms:
if form.is_valid():
form.save()
else:
formset = CampaignStatusFormSet(queryset=queryset)
campaigns_and_forms = list(zip(queryset, formset))
context = {
'formset': formset,
'campaigns_and_forms': campaigns_and_forms,
}
return render(request, 'campaigns_in_progress.html', context)
'''
I have 2 views: display_quote and quote_create.
def display_quote(request, pk):
items_quote = Quote.objects.filter(pk=pk)
items_quote_line = LineQuote.objects.all().filter(num_quote_id=pk)
form = QuoteLineForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
form.save()
total = 0
for item in items_quote_line:
total = total + item.get_price()
context = {'items_quote': items_quote,
'items_quote_line': items_quote_line,
'form': form,
'total':total
}
return render(request, 'quote/quote_display.html', context)
def quote_create(request):
form = QuoteForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
form.save()
return render(request, 'quote/quote_create.html', {'form': form})
After creating a quote, I want to redirect to "display_quote" (the quote creted).
Error obtained:
The view quote.views.quote_create didn't return an HttpResponse object. It returned None instead.
def quote_create(request):
form = QuoteForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
form.save()
return render(request, 'quote/quote_create.html', {'form': form})
return render(request, "...", {})
return something by default. Else conditions are not handled here...
I have two forms, one CreateOrderForm and one CreateManifestForm. Submitting CreateOrderForm renders CreateManifestForm.
There is an input in CreateOrderForm 'reference' which is user entered but then should default into the 'reference field of CreateManifestForm. I seem to be unable to figure out how to pass that value from form to form
FORMS.PY
class CreateOrderForm(forms.ModelForm):
class Meta:
model = Orders
fields = ('reference', 'ultimate_consignee', 'ship_to', 'vessel', 'booking_no', 'POL',....)
class CreateManifestForm(forms.ModelForm):
class Meta:
model = Manifests
fields = ('reference', 'cases', 'description', 'count')
VIEWS.PY
def add_order(request):
if request.method == "POST":
form = CreateOrderForm(request.POST)
if form.is_valid():
form.save()
return redirect('add_manifest')
else:
form = CreateOrderForm()
return render(request, 'add_order.html', {'form': form})
def add_manifest(request):
if request.method == "POST":
form = CreateManifestForm(request.POST)
if form.is_valid():
form.save()
return redirect('add_manifest')
form = CreateManifestForm()
manifests = Manifests.objects.all()
context = {
'form': form,
'manifests': manifests,
}
return render(request, 'add_manifest.html', context)
As you can see there is a field in each form for 'reference' I would like to user enter it in CreateOrderForm and pass that value to default when creating the manifest. Any help is greatly appreciated and thank you in advance.
There is a solution that you can try:
make the add_manifest URL have a Parameter like
path('add-manifest/<int:reference_id>/', name='add_manifest`)
and in your View update:
return redirect('add_manifest') # in add_order function
to:
return redirect('add_manifest', kwargs={'reference_id': form.reference})
now in the add_manifest View you can access the Reference from:
request.resolver_match.kwargs.get('reference_id')
I defined an initial value to my title field, but once I execute it, it shows no error and the initial value is not showing in my field how do I solve it? Thanks
def form_view(request):
if request.method == "POST":
initial_data = {
'title': 'default title'
}
form = ProductForm(request.POST, initial=initial_data)
if form.is_valid():
form.save()
form = ProductForm()
else:
form = ProductForm()
return render(request, "form.html", {"form": form})
You've put it in the wrong place. If you want it to show when the form is first rendered, you shouldn't put it in the POST block - which is called when the form is submitted - but the else block.
if request.method == 'POST':
form = ProductForm(request.POST)
...
else:
form = ProductForm(initial=initial_data)