How to fix unbound local error on django? - django

I have written this code. Every time I assign a variable I am getting "local variable 'obj' referenced before assignment". I don't know where I did wrong.
This is my view.py file:
def blog_detail(request, slug):
queryset = Blog.objects.filter(slug=slug)
if queryset.count() == 1:
obj = queryset.first()
templates = "temp_app.html"
context = {"object": obj}
return render(request, templates, context)
Here is my models.py file
class Blog(models.Model):
title = models.TextField()
slug = models.SlugField()
content = models.TextField(null=True, blank=True)
every time I run the server I am getting UnboundLocalError.
bt if I use "queryset" without assigning it into "obj" I don't get the error.
I am getting the error after assigning the "queryset" in "obj". Where am I doing wrong?

That mean you should add the obj variable before if conditional. In your case, the result of queryset variable is not 1.
queryset = Blog.objects.filter(slug=slug)
if queryset.count() == 1:
obj = queryset.first()
to;
obj = None # or whatever your need.
queryset = Blog.objects.filter(slug=slug)
if queryset.count() == 1:
obj = queryset.first()
or;
queryset = Blog.objects.filter(slug=slug)
if queryset.count() == 1:
obj = queryset.first()
else:
obj = None # or whatever your need.

Related

AttributeError at /profile/chandan 'tuple' object has no attribute 'another_user'

I am trying to get follower system to work but it just wont work
class Followers(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
another_user = models.ManyToManyField(User, related_name='another_user')
def __str__(self):
return self.user.name
def profile(request, user_name):
user_obj = User.objects.get(username=user_name)
session_user, create = User.objects.get(username=user_name)
session_following, create = Followers.objects.get_or_create(user=session_user)
following = Followers.objects.get_or_create(user=session_user.id)
check_user_followers = Followers.objects.filter(another_user=user_obj)
is_followed = False
if session_following.another_user.filter(username=user_name).exists() or following.another_user.filter(username=user_name).exists():
is_followed=True
else:
is_followed=False
param = {'user_obj': user_obj,'followers':check_user_followers, 'following': following,'is_followed':is_followed}
if 'user' in request.session:
return render(request, 'users/profile2.html', param)
else:
return redirect('index')
I am getting the error:
AttributeError at /profile/chandan
'tuple' object has no attribute 'another_user'
get_or_create(…) [Django-doc] returns a 2-tuple with as first item the object, and as second item a boolean that indicates if the object was created (True), or already in the database.
You can make use of iterable unpacking to set the boolean to a "throwaway" variable:
# ↓ throw away the second item of the 2-tuple
session_following, __ = Followers.objects.get_or_create(user=session_user)
following, __ = Followers.objects.get_or_create(user=session_user)

not able to save data in django form

I am getting error Cannot assign "'1'": "dropdown.drp1" must be a "basedrop" instance. I am sharing my code. Kindly help. I got some solutions on stack but I did not understand how to implement that in my case. Django error. Cannot assign must be an instance
models.py
class basedrop(models.Model):
name = models.CharField(max_length=50,blank=False,null=False)
def __str__(self):
return self.name
class subdrop(models.Model):
name = models.CharField(max_length=100,blank=False,null=False)
bsdrop = models.ForeignKey(basedrop,null=False,blank=False,on_delete=models.CASCADE)
def __str__(self):
return self.name
class lastdrop(models.Model):
name = models.CharField(max_length=100,blank=False,null=False)
sbdrop = models.ForeignKey(subdrop,null=False,blank=False,on_delete=models.CASCADE)
def __str__(self):
return self.name
class dropdown(models.Model):
name = models.CharField(max_length=50)
drp1 = models.ForeignKey(basedrop,max_length=50,on_delete=models.CASCADE)
drp2 = models.ForeignKey(subdrop,max_length=50,on_delete=models.CASCADE)
drp3 = models.ForeignKey(lastdrop,max_length=50,on_delete=models.CASCADE)
def __str__(self):
return self.name
views.py
def create_drop(request):
if request.method == 'POST':
form = dropdownForm(request.POST or None)
if form.is_valid():
form = dropdown(name=request.POST.get('name'),drp1_Id=int(request.POST.get('drp1')),
drp2_Id=int(request.POST.get('drp2')),drp3_Id=int(request.POST.get('drp3')))
form.save()
return HttpResponse('<p>this is working</p>')
form = dropdownForm()
return render(request,'drop.html',{'form':form})
forms.py
class dropdownForm(forms.ModelForm):
drp1 = forms.ChoiceField(choices=((bs.get('id'),bs.get('name')) for bs in basedrop.objects.all().values('id','name')))
class Meta:
model = dropdown
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['drp2'].queryset = subdrop.objects.none()
self.fields['drp3'].queryset = lastdrop.objects.none()
if 'drp1' in self.data:
try:
country_id = int(self.data.get('drp1'))
self.fields['drp2'].queryset = subdrop.objects.filter(id=country_id).order_by('name')
except (ValueError, TypeError):
pass
elif 'drp2' in self.data:
try:
country_id = int(self.data.get('drp2'))
self.fields['drp3'].queryset = lastdrop.objects.filter(id=country_id).order_by('name')
except (ValueError, TypeError):
pass
elif self.instance.pk:
self.fields['drp2'].queryset = self.instance.drp1.city_set.order_by('name')
self.fields['drp3'].queryset = self.instance.drp2.city_set.order_by('name')
I don't know if it could cause failures but you're passing the POSTed argument 'drp1' as integer for drp1_Id, drp2_Id and drp3_Id.
You'd have it much easier if you choose a more intuitive coding style.
For example this line:
form = dropdown(name=request.POST.get('name'), drp1_Id=int(request.POST.get('drp1')), drp2_Id=int(request.POST.get('drp1')), drp3_Id=int(request.POST.get('drp1')))
If you get the objects and pass them to the dropdown you gain readability specially if there is an error:
drp1_pk = request.POST.get('drp1')
drp1 = basedrop.objects.get(pk=drp1_pk)
drp2 = subdrop.objects.get(pk=drp1_pk)
drp3 = lastdrop.objects.get(pk=drp1_pk)
form = dropdown(name=request.POST.get('name'), drp1=drp1, drp2=drp2, drp3=drp3)
But again:
It looks strange to pass the same primary key to three different models.

Django 'Post' object has no attribute '__getitem__'

I'd like to append a quoted pots to user's post before saving it.
Here is the view:
#login_required
def quote_reply(request, quote_id):
tform = PostForm()
print 'quote_id is:' + quote_id
quote = Post.objects.get(pk = quote_id)
topic_id = quote.topic_id
topic = Topic.objects.get(id= topic_id)
print 'quote is' + quote.body
args = {}
if request.method == 'POST':
post = PostForm(request.POST)
if post.is_valid():
p = post.save(commit = False)
p.topic = topic
p.title = post.cleaned_data['title']
p.body = post.cleaned_data['body']
p['body'].append(str(quote)) #problematic line
p.creator = request.user
p.user_ip = request.META['REMOTE_ADDR']
if len(p.title)< 1:
p.title=p.body[:60]
p.save()
tid = int(topic_id)
return HttpResponseRedirect('/forum/topic/%s' % topic_id)
else:
args.update(csrf(request))
args['form'] = tform
args['post'] = quote
args['topic_id'] = topic_id
return render_to_response('myforum/qoute_reply.html', args,
context_instance=RequestContext(request))
I tried also tried
p['body'].append(unicode(quote))
but gives the same error.
Appreciate your help to resolve this.
Update: Here is the Post model
class Post(models.Model):
title = models.CharField(max_length=75, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
creator = models.ForeignKey(User, blank=True, null=True)
updated = models.DateTimeField(auto_now=True)
topic = models.ForeignKey(Topic)
body = models.TextField(max_length=10000)
user_ip = models.GenericIPAddressField(blank=True, null=True)
def __unicode__(self):
return u"%s - %s - %s" % (self.creator, self.topic, self.title)
def short(self):
return u"%s - %s\n%s" % (self.creator, self.title, self.created.strftime("%b %d, %I:%M %p"))
short.allow_tags = True
Not sure what to do.
The main problem here is that p is a model instance, which does not support dict-style attribute access syntax. To access the post attribute, use the standard dot syntax, p.post.
The second problem is that you can't use append to change a Unicode or string object - they're immutable. Instead, you should create a new Unicode object containing the content you want and assign that. For instance:
p.post = post.cleaned_data['body'] + unicode(quote)

django custom manager with filter parameter

I would like to add a custom manager which can be called from a template, but does not affect the entire model (e.g. admin views) and which listens to a parameter set in the request (user_profile).
The following is what I have so far:
models.py:
class CurrentQuerySet(models.query.QuerySet):
def current(self):
return self.filter(id=1) ## this simplified filter test works..
class CurrentManager(models.Manager):
use_for_related_fields = True
def get_query_set(self):
return CurrentQuerySet(self.model)
def current(self, *args, **kwargs):
return self.get_query_set().current(*args, **kwargs)
For model B is defined:
objects = CurrentManager()
The template calls:
{% for b in a.b_set.current %}
But as soon as I try to pass a parameter to that filter (in this case a date stored on the user-profile) the method does not return any results.
e.g.:
models.py
class CurrentQuerySet(models.query.QuerySet):
def current(self,my_date):
return self.filter(valid_from__lte=my_date)
showA.html
{% for b in a.b_set.current(request.user.get_profile.my_date) %}
Instead of passing the parameter from the template, I have also tried to set this in the view.py
#login_required
def showA(request,a_id):
my_date = request.user.get_profile().my_date
a = A.objects.get(id=a_id)
t = loader.get_template('myapp/showA.html')
c = RequestContext(request,{'a':a,'my_date':my_date,})
return HttpResponse(t.render(c))
Which part am I missing (or misunderstanding) here?
Thanks
R
Edit
Here the models. As mentioned, in this example it's a simple 1:n relationship, but can also be m:n in other cases.
class A(models.Model):
#objects = CurrentManager()
a = models.CharField(max_length=200)
description = models.TextField(null=True,blank=True)
valid_from = models.DateField('valid from')
valid_to = models.DateField('valid to',null=True,blank=True)
def __unicode__(self):
return self.a
class B(models.Model):
#objects = models.Manager()
objects = CurrentManager()
a = models.ForeignKey(A)
b = models.CharField(max_length=200)
screenshot = models.ManyToManyField("Screenshot",through="ScreenshotToB")
description = models.TextField(null=True,blank=True)
valid_from = models.DateField('valid from')
valid_to = models.DateField('valid to',null=True,blank=True)
def __unicode__(self):
return self.b
Edit-2
The accepted answer works for at least one relationship.
In case of a more nested data model, this method seems not to deliver the expected results:
models.py
class C(models.Model):
objects = CurrentManager()
b = models.ForeignKey(A)
c = models.CharField(max_length=200)
description = models.TextField(null=True,blank=True)
valid_from = models.DateField('valid from')
valid_to = models.DateField('valid to',null=True,blank=True)
def __unicode__(self):
return self.c
views.py
#login_required
def showA(request,a_id):
a = A.objects.get(id=a_id)
my_date = request.user.get_profile().my_date
b_objects = a.b_set.current(my_date)
c_objects = b_objects.c_set.current(my_date)
t = loader.get_template('controltool2/showA.html')
c = RequestContext(request,{'a':a,'b_objects':b_objects,'c_objects':c_objects,})
return HttpResponse(t.render(c))
This returns the error: 'QuerySet' object has no attribute 'c_set'.
I'd simplify it:
class CurrentManager(models.Manager):
def current(self, my_date):
return super(CurrentManager, self).get_query_set().filter(valid_from__lte=my_date)
and then use it like this:
a = A.objects.get(id=a_id)
my_date = request.user.get_profile().my_date
b_objects = a.b_set.objects.current(my_date)
and then just pass a to the template as the filtered objects accessing them using this:
{% for b in b_objects %}
Hope this helps!
Edit (by requestor):
I had to adjust it as follows to get it working:
a = A.objects.get(id=a_id)
my_date = request.user.get_profile().my_date
b_objects = a.b_set.current(my_date)
This threw an error: "'RelatedManager' object has no attribute 'objects'"
a.b_set.objects.current(my_date)

IntegrityError error while saving value of to foreign key in django

Hey folks i am getting integrity error while saving my views .Please tell me what i am doing wrong
Here is my django model
class Ruleinfo(models.Model):
rule = models.IntegerField(null=False)
From = models.IPAddressField(null=True)
to = models.IPAddressField(null=True)
priority = models.ForeignKey('Priority',related_name='pri_no')
cisp =models.ForeignKey('Priority',related_name = 'CISP_no')
def __unicode__(self):
return u'%s' %(self.rule)
class Priority(models.Model):
pri = models.IntegerField(null = True)
Ruleno = models.ForeignKey('Ruleinfo',related_name = 'ruleno_no')
CISP = models.IntegerField(null = True)
def __unicode__(self):
return u'%s ' % (self.priority)
My model form is looking like .
class RuleInfoForm(ModelForm):
class Meta:
model = Ruleinfo
fields = ("rule","From","to")
here is my views.py
def multiwanrule_info(request):
data = {}
no_of_isp = MultiWAN.objects.all()
try:
form = RuleInfoForm(request.POST)
except:
pass
print "----------------------------printing form"
print form
if form.is_valid():
rl_frm = form.save(commit=False)
get_priorities = request.POST.getlist('priority')
get_cisp_info = request.POST.getlist('cisp')
rule_object = Ruleinfo()
for get_pri,get_ci in zip(get_priorities,get_cisp_info,):
pri_object = Priority.objects.get_or_create(Ruleno = rule_object)
pri_object.pri = get_pri
pri_object.CISP = get_ci
rl_frm.save()
else:
form = RuleInfoForm()
data['form'] = form
data['number_of_isp'] = no_of_isp
return render_to_response('networking.html',data)
I am getting the above error along this
networking_priority.Ruleno_id may not be NULL
help me out so that i could get back on track .
rule_object = Ruleinfo()
This just instantiates a new model object. It is not saved or assigned values. Since it is not saved it does not have an id value.
assigning your rule_object values: rule, from, to, priority, and cisp values, should fix your problem.