local variable 'product' referenced before assignment ? in Django - python

I am facing the issue I can't find the solution yet. It's working so far. but now showing an error. don't know how to fix this. please need help.
views.py
def add_product(request):
product_form = ProductForm()
product_variant_images_form = ProductVariantsImagesForm()
if request.method == 'POST':
product_form = ProductForm(request.POST)
product_variant_images_form = ProductVariantsImagesForm(request.POST,request.FILES)
if product_form.is_valid():
print(request.POST)
product = product_form.save(commit=False)
vendor = CustomUser.objects.filter(id=request.user.id)
product.vendoruser = vendor[0]
product.save()
vendor = CustomUser.objects.get(id=request.user.id)
product_variant = ProductVariants()
product_variant.product_id = product ###ERROR SHOWING IN THIS LINE
product_variant.vendoruser = vendor
product_variant.price = request.POST.get('price')
product_variant.initial_stock = request.POST.get('initial_stock')
product_variant.weight_of_product = request.POST.get('weight_of_product')
product_variant.save()
return redirect('vendor:inventory_display')
else:
productform = ProductForm()
productvariantsform = ProductVariantsForm()
product_variant_images_form = ProductVariantsImagesForm()
return render(request, 'vendor/add_product.html',
{'productform': productform,'product_variant_images_form':product_variant_images_form,
'productvariantsform': productvariantsform})
It's working fine.After product added multiple time the error occurred. how can I get rid of this error.please some help much appreciated.

Its because your product variable isn't set if you don't go inside if product_form.is_valid():,
you could just set a default value before this if statement in order to fix your error.
I hope this helped.

The product variable is only defined if the form is valid. Either you can set a default value for product outside of the if statement or you could move all of the code involving data from the form inside of the if statement.

Related

How to insert ManyToMany field in django

I want to insert a ManyToMany fields in my db using django.I select some customers using checkboxes.
This is my models.py :
class Campaign(models.Model):
title = models.CharField(max_length=255)
channel = models.CharField(max_length=255)
start_date = models.DateField()
end_date = models.DateField()
target_prospect = models.ManyToManyField(ProspectClient,related_name='campaigns_prospect')
target_partner = models.ManyToManyField(PartnerClient,related_name='campaigns_partners')
I try the code below in my views.py but didn't work :
def campaigns_page(request):
if request.user.is_authenticated:
if request.user.profile == 'D' or request.user.profile == 'E' or request.user.is_superuser:
campaigns = Campaign.objects.all()
prospects = ProspectClient.objects.all()
partners = PartnerClient.objects.exclude(id__in=PartnerClient.objects.values('id')).all()
context = {
'campaigns':campaigns,
'prospects':prospects,
'partners':partners
}
if request.method == 'POST':
title = request.POST['title']
channel = request.POST['channel']
start_date = request.POST['start_date']
end_date = request.POST['end_date']
descriptions = request.POST['goals'].split(",")
targets = request.POST['targets']
campaign = Campaign.objects.create(title=title,channel=channel,start_date=start_date,end_date=end_date)
for description in descriptions:
goal = Goal.objects.create(description=description)
goal.campaign.add(campaign)
for target in targets:
prospects.campaign.add(campaign)
partners.campaign.add(campaign)
return render(request,'CampaignManagement/campaigns_page.html',context)
return render(request, 'Login/logout.html')
If I delete the part of tergets it works.
But with this part it gives me This error : 'QuerySet' object has no attribute 'campaign'
How I can solve this ?
I see a couple of errors. Perhaps one or more are leading to the problem.
One
Try printing this:
partners = PartnerClient.objects.exclude(id__in=PartnerClient.objects.values('id')).all()
print(partners)
I suspect it will print None since you are excluding all id's in PartnerClient.objects.values('id'). On another note you don't need the all() since exclude() will return all the results you are looking for.
Two
In the line for target in targets: what exactly are you iterating through? targets = request.POST['targets'] is just giving you a string, so it would iterate through each letter. Perhaps you meant:
targets = request.POST['targets'].split(", ")
like you did for descriptions? Or perhaps you are getting a list of items from your form, in which case you can use:
targets = request.POST.getlist('targets')

Django check if post value exists in db

I'm trying to submit two forms with one submit button. First I want to check if form 1 already exists in the db, if id does then just post the second form using the "ticker" from first form as Foreginkey. But seem to get an error:
'UserTickerForm' object has no attribute 'get'
My code:
if request.method == 'POST':
request_form_user_ticker = UserTickerForm(request.POST)
request_form_trade = TradesForm(request.POST)
if request_form_user_ticker.is_valid() and request_form_trade.is_valid():
if not User_Ticker.objects.filter(portfolio=select_portfolio, ticker=request_form_user_ticker.get('ticker')).exists():
user_ticker_instace = request_form_user_ticker.save(commit=False)
user_ticker_instace.portfolio = select_portfolio
user_ticker_instace.save()
trade_instance = request_form_trade.save(commit=False)
trade_instance.ticker = request_form_user_ticker.get('ticker')
trade_instance.save()
else:
trade_instance = request_form_trade.save(commit=False)
trade_instance.ticker = request_form_user_ticker.get('ticker')
trade_instance.save()
Does anyone know who this is happening and what I can do to fix this?
instead of request_form_user_ticker.get('ticker') you should call .get('ticker') on cleaned data so request_form_user_ticker.cleaned_data.get('ticker')

django get_or_create method always results in a new record

Model
class projects(models.Model):
"""Table that holds the details of the projects."""
toiName = models.CharField(max_length=100)
toiOwner = models.CharField(max_length=50)
receiver = models.CharField(max_length=50)
manager = models.CharField(max_length=50)
toiOwnerEmail = models.EmailField(max_length=70)
receiverEmail = models.EmailField(max_length=70)
managerEmail = models.EmailField(max_length=70)
dateUpdated= models.DateTimeField(default=datetime.today())
dateCreated = models.DateTimeField(default=datetime.today())
class Meta:
db_table="projects"
View, the original code to save the model works fine, when I go ahead and edit the form in the view, I always end up with a new record.
data = model_to_dict(projects.objects.filter(toiName=pid, managerEmail=request.user)[0])
if request.method == 'POST':
form = projectsForm(request.POST)
if form.is_valid():
#form = projectsForm(request.POST, instance=projects.objects.get(toiName=pid))
#obj = projects\
obj, created = projects.objects.get_or_create\
(toiName=request.POST['toiName'],
toiOwnerEmail=request.POST['toiOwnerEmail'],
toiOwner=request.POST['toiOwner'],
manager=request.POST['manager'],
receiver=request.POST['receiver'],
receiverEmail=request.POST['receiverEmail'],
dateUpdated=datetime.now(),
dateCreated=data['dateCreated'],
managerEmail=request.user,)
Here created always results in True.
At least this dateUpdated=datetime.now() causes get_or_create to always create new record, because each time datetime.now() is different.
I believe I was using the get_or_create incorrectly, since I was only trying to update the entry.
I fixed the code in the view with:
data = model_to_dict(projects.objects.filter(toiName=pid, managerEmail=request.user)[0])
proj = projects.objects.get(toiName=pid, managerEmail=request.user)
if request.method == 'POST':
form = projectsForm(request.POST)
if form.is_valid():
proj.toiName=form.cleaned_data['toiName']
proj.toiOwnerEmail=form.cleaned_data['toiOwnerEmail']
proj.toiOwner=form.cleaned_data['toiOwner']
proj.manager=form.cleaned_data['manager']
proj.receiver=form.cleaned_data['receiver']
proj.receiverEmail=form.cleaned_data['receiverEmail']
proj.dateUpdated=datetime.now()
#proj.dateCreated=data['dateCreated']
proj.save()
additional to #user1865366 answer, projects.objects.get should be enclose it with try ... except ... like so
try:
proj = Projects.objects.get(toiName=pid,manageEmail=request.user)
except Projects.DoesNotExist :
# do something create new proj and do something with the form
...
otherwise there will be big error screen when django cannot get the object

change a form value before validation in Django form

I have a django form and on my view function I do this :
search_packages_form = SearchPackagesForm( data = request.POST )
I would like to overwrite a form field called price which is decleared as such :
price = forms.ChoiceField( choices = PRICE_CHOICES, required = False,widget = forms.RadioSelect )
I would like to overwrite the form field before calling search_packages_form.is_valid()
I thought of doing :
search_packages_form.data['price'] = NEW_PRICE
But it does not work. Any ideas ?
Probably not the Django way but based on https://stackoverflow.com/a/17304350/2730032 I'm guessing the easiest way to change your form value before validation is to do something like the following:
def search_packages_view(request):
if request.method == 'POST'
updated_request = request.POST.copy()
updated_request.update({'price': NEW_PRICE})
search_packages_form = SearchPackagesForm(updated_request)
if search_packages_form.is_valid():
# You're all good
This works but I'd be interested if anyone has another way that seems more in line with Django, or if there isn't: then an explanation about why.
one trick for what you want is to do it like this:
changed_data = dict(request.POST)
changed_data['price'] = NEW_PRICE
search_packages_form = SearchPackagesForm(data = changed_data)
My solution is build on an earlier proposal. It is a working solution, which can be used in several cases.
#Milad Khodabandehloo
had a tricky solution to solve the problem.
changed_data = dict(request.POST)
changed_data['price'] = NEW_PRICE
search_packages_form = SearchPackagesForm(data = changed_data)
as #The EasyLearn Academy commented: it does not allow you to access actual data submitted in form.
This is because the request.POST is immutable.
But there is a solution to the problem - just have to be more tricky.
This solution is only good if a reference to the object is enough for the certain cause. It leaves the object itself the same.
# write object to variable (data)
data = request.POST
# set to mutable
data._mutable = True
# modify the values in data
data[modified_field] = new_value
# set mutable flag back (optional)
data._mutable = False
Hope it's useful!
form.is_valid() runs through your form's (and model's in case of a ModelForm) clean method's, returning True or False
If you plan on changing form data you can do it within the general clean method or at field level, e.g.
class YourForm(DerivingClass):
# regular stuff
def clean_<ATTR>(self):
# here
return self.cleaned_data
def clean(self):
# or here
return super(YourForm, self).clean()

Django: strange IntegrityError upon saving a ModelFormset form

I am trying to save a couple ModelFormset forms, but am running into an IntegrityError. Here is the code:
billing_formset = BillingFormSet(request.POST,prefix='billing')
cc_formset = CCFormSet(request.POST,prefix='cc')
if billing_formset.is_valid() and cc_formset.is_valid():
bp = UserBillingProfile()
cc = UserCreditCard()
for form in billing_formset.forms:
billing_profile = form.save(commit=False)
billing_profile.user = request.user
bp = billing_profile.save()
for form in cc_formset.forms:
cc = form.save(commit=False)
cc.billing_profile = bp
cc = form.save()
This code caused the following code:
IntegrityError at [url removed]
(1048, "Column 'user_billing_profile_id' cannot be null")
EDIT: Here is some iterative code that also fixes my typo. I'm running into basically the same problem.
billing_profile_form = billing_formset.forms[0]
cc_form = cc_formset.forms[0]
unsaved_billing_profile = billing_profile_form.save(commit=False)
user_billing_profile = unsaved_billing_profile.save()
unsaved_cc = cc_form.save(commit=False)
unsaved_cc.user_billing_profile = user_billing_profile
cc = unsaved_cc.save()
Problem line gives: "Cannot assign None: "UserCreditCard.user_billing_profile" does not allow null values." It seems unsaved_billing_profile.save() is returning null? Why?
This is kind of crazy; everything seems to be right. I don't get any errors when saving the billing profile. Any ideas on what I should check? Things seem to be going wrong in the second loop, where bp apparently has a value of None.
Thanks in advance.
This means you are trying to save a model instance with user_billing_profile set to None, looks like you are calling "billing_profile" instead of "user_billing_profile".
The "save" method returns None every time commit=False isn't specified. you should instead call something like this:
billing_profile.save()
bp = billing_profile.instance

Categories

Resources