local variable 'form' referenced before assignment - django-forms

My View :
def refer(request, seek_id):
seek_obj = SeekSolutions.objects.get(pk = seek_id)
if request.method == 'POST':
form = SeekReferForm(request.POST)
if form.is_valid():
obj = form.save(commit = False)
obj.refferer = request.user
obj.seek_id = seek_obj
obj.save()
send_message(obj)
return HttpResponseRedirect('/seek/referred')
return render_to_response('seek/refer.html', {'form' : form , } )
Traceback :
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/handlers/base.py in get_response
response = callback(request, *callback_args, **callback_kwargs) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/admin/options.py in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/decorators.py in _wrapped_view
response = view_func(request, *args, **kwargs) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/views/decorators/cache.py in _wrapped_view_func
response = view_func(request, *args, **kwargs) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/admin/sites.py in inner
return view(request, *args, **kwargs) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/decorators.py in _wrapper
return bound_func(*args, **kwargs) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/decorators.py in _wrapped_view
response = view_func(request, *args, **kwargs) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/decorators.py in bound_func
return func(self, *args2, **kwargs2) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/admin/options.py in changelist_view
'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)}, ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/query.py in __len__
self._result_cache = list(self.iterator()) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/query.py in iterator
for row in compiler.results_iter(): ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/sql/compiler.py in results_iter
for rows in self.execute_sql(MULTI): ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/sql/compiler.py in execute_sql
cursor.execute(sql, params) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/backends/util.py in execute
return self.cursor.execute(sql, params) ...
▶ Local vars
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py in execute
return Database.Cursor.execute(self, query, params) ...
▶ Local vars

Although this question is pretty old, since I ran in to the same problem(and just solved it) I think I ought to answer to it for future references. But then I had a different error. But you seem to be missing something in your code.
def refer(request, seek_id):
seek_obj = SeekSolutions.objects.get(pk = seek_id)
if request.method == 'POST':
form = SeekReferForm(request.POST)
if form.is_valid():
obj = form.save(commit = False)
obj.refferer = request.user
obj.seek_id = seek_obj
obj.save()
send_message(obj)
return HttpResponseRedirect('/seek/referred')
else:
form = SeekReferForm()
return render_to_response('seek/refer.html', {'form' : form , } )
This includes an else block to your first if. This is because when you try to access the url from your browser, you are essentially doing a GET request on the resource. As a result the first if is violated and comes directly to the return statement where it tries to return a dictionary item with 'form' as the key and a form object which was never created at all. Thus the error in your code. There need to be an else part which is supposed to instantiate the form object in case you try to open the url in your browser. I hope that helps the cause.

the form is instantiated only when request.method == 'POST'.

Related

How to implement Elasticsearch advanced search with DRF

I want to implement a search in Elastic Search with Django Rest Framework. I have a form for searching as follows.
I used a serializer to implement this form.
search.py:
class AdvancedSearch(mixins.ListModelMixin, viewsets.GenericViewSet):
serializer_class = AdvancedSearchSerializer
def query_builder(self, *args, **kwargs):
## building related query
return query
#get_db()
def get_queryset(self, db=None, *args, **kwargs):
serializer = self.get_serializer(data=self.request.data)
serializer.is_valid(raise_exception=True)
query = self.query_builder(search_input=serializer.validated_data)
response = db.search(query) # query the elastic with elasticsearch-dsl and return the results
if not response:
raise NoteFound()
return response
def list(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
self.serializer_class = AdvancedSearchSerializer
return super(AdvancedSearch, self).list(request, *args, **kwargs)
serializer.py:
class AdvancedSearchSerializer(serializers.Serializer):
metadata_choices = [('', ''), ...]
name = serializers.CharField(required=False, label='Name')
type = serializers.CharField(required=False, label='Type')
metadata = serializers.CharField(required=False, label='Metadata')
metadata_fields = serializers.MultipleChoiceField(allow_blank=True, choices=metadata_choices)
submit_date = serializers.DateTimeField(required=False)
def to_representation(self, instance):
output = {}
output['es_id'] = instance.meta.id
for attribute_name in instance:
attribute = getattr(instance, attribute_name)
if isinstance(attribute, (str, int, bool, float, type(None))):
# Primitive types can be passed through unmodified.
output[attribute_name] = attribute
elif isinstance(attribute, list):
# Recursively deal with items in lists.
output[attribute_name] = [
self.to_representation(item) for item in attribute
]
elif isinstance(attribute, (dict, AttrDict)):
temp = attribute.to_dict()
for key, value in temp.items():
print(key,value)
# Recursively deal with items in dictionaries.
output[attribute_name] = {
str(key): value
for key, value in temp.items()
}
else:
# Force anything else to its string representation.
output[attribute_name] = attribute
output['highlight'] = instance.meta.highlight.to_dict()
return [output]
With this code, I get the expected result, but I was wondering if this is a right approach.
And also in to_representation I have access to each result, but how can I add a total value like the number of results.
Thanks in advance.

Return a different Content-Type Reponse on error

Given an endpoint with one renderer:
class PNGRenderer(BaseRenderer):
media_type = 'image/png'
format = 'png'
def render(self, data, media_type=None, renderer_context=None):
return data
#renderer_classes((PNGRenderer, ))
def some_endpoint(request, format=None):
filename = 'foo.png'
if not os.path.exists(filename):
raise NotFound("File not found")
else:
with open(filename, 'rb') as f:
data = f.read()
return response(data)
I would like to return application/json in case foo.png is not found. In real life filename not constantly "foo.png" but dynamic, obviously.
How can I return json such that Content-Type is properly set to application/json in the response even though format='png' was provided to the endpoint.
While writing the question, I found the answer for changing the renderer: request.accepted_renderer = JSONRenderer().
In particular:
#renderer_classes((PNGRenderer, ))
def some_endpoint(request, format=None):
filename = 'foo.png'
if not os.path.exists(filename):
request.accepted_renderer = JSONRenderer()
raise NotFound("File not found")
else:
with open(filename, 'rb') as f:
data = f.read()
return response(data)
I am not sure if this a a proper way to deal with exceptions for binary Content-Type's.

Python using multiple decorators on a method and logging the method name inside each decorator

Assume I have two decorator functions in a file log.py
def timeit(logger, level = 'DEBUG'):
def timeit_decorator(method):
def timeit_wrapper(*args, **kw):
ts = time.time()
result = method(*args, **kw)
te = time.time()
logger.log(logging.getLevelName(level), '%2.4f sec' % (te - ts), extra = dict(filename = method.__code__.co_filename, funcName = method.__code__.co_name))
return result
return timeit_wrapper
return timeit_decorator
And I have a file test.py having one function which uses both the decorators like this,
#timeit(logger = LOGGER)
#logargs(logger = LOGGER)
def test(arg1 = 'something'):
pass
When I run test.py one of the decorator prints module, func & lineno as [test.py:7 - test() ]
and other one prints like [log.py:6 - timeit_wrapper()]
How do I make both the decorator to print the actual method, module & lineno which is [test.py:7 - test() ]

How to return a particular value from a method?

I have this code that tries to return a value from a method:
temp = "123"
return temp
and I have this line that calls the method and assigns the return value:
person_connections = #client.get_person_connections(:id => current_user_id )
but when I try to inspect person_connections, it shows some different object string. Any idea how to return the actual value of the temp variable?
def get_person_connections(options = {})
person_id = options[:id]
path = "/people/id=" + person_id + ":(num-connections)"
query_connections(path, options)
self
end
and
private
def query_connections(path, options={})
fields = options.delete(:fields) || LinkedIn.default_profile_fields
if options.delete(:public)
path +=":public"
elsif fields
path +=":(#{fields.map{ |f| f.to_s.gsub("_","-") }.join(',')})"
end
headers = options.delete(:headers) || {}
params = options.map { |k,v| v.is_a?(Array) ? v.map{|i| "#{k}=#{i}"}.join("&") : "#{k}=#{v}" }.join("&")
path += "?#{params}" if not params.empty?
temp_var = get(path, headers)
hash = JSON.parse(temp_var)
conn = hash["numConnections"]
end
As Samy said in a comment:
In Ruby, the last statement will be returned.
So if we take a look at get_person_connections, we see that the last line is self. What it means is that it returns the instance on which the method was called, #client in this case.
Additional notes: the solution would be to remove self, although if the method is used elsewhere be careful as returning self is often used to allow chaining of methods (though it hardly makes sense to do that on a get method).

django: _init_ def work but does not update to class in django form

this is my form:
class IPTrackerSearchForm(forms.Form):
keyword = forms.CharField(max_length=100, widget=forms.TextInput(attrs={'size':'50'}))
search_in = forms.ChoiceField(required=False, choices=ANY_CHOICE + MODULE_SEARCH_IN_CHOICES)
product = forms.CharField(max_length=64,widget=forms.TextInput(attrs={'size':'50'}))
family = forms.CharField(max_length=64,widget=forms.TextInput(attrs={'size':'50'}))
temp_result = Merlin.objects.values('build').distinct()
result = [(value['build'], value['build']) for value in temp_result]
build = forms.ChoiceField(choices=ANY_CHOICE + result)
circuit_name = forms.CharField(max_length=256,widget=forms.TextInput(attrs={'size':'50'}))
parameterization = forms.CharField(max_length=1024,widget=forms.TextInput(attrs={'size':'50'}))
metric = forms.CharField(max_length=64,widget=forms.TextInput(attrs={'size':'50'}))
show_in_one_page = forms.BooleanField(required=False, label="Show filtered result in one page", widget=forms.CheckboxInput(attrs={'class':'checkbox'}))
def __init__(self, *args, **kwargs):
super(IPTrackerSearchForm, self).__init__(*args, **kwargs)
temp_result = Merlin.objects.values('build').distinct()
self.result = [(value['build'], value['build']) for value in temp_result]
self.build = forms.ChoiceField(choices=ANY_CHOICE + self.result)
print self.result
With the purpose that, each time I refresh the webpage, when have new record to "build" column in database. It should update to the drop down box "build" here but It never update unless restart the server. I use print and see that __init__ detect new record but can not refect to build in Class.
Many thanks
You actually need to update self.fields['build'] instead of self.build.
def __init__(self, *args, **kwargs):
super(IPTrackerSearchForm, self).__init__(*args, **kwargs)
temp_result = Merlin.objects.values('build').distinct()
result = [(value['build'], value['build']) for value in temp_result]
self.fields['build'] = forms.ChoiceField(choices=ANY_CHOICE + result)
print result
Because you're not updating self.fields, you are seeing the result of the query at compile time, not execution.

Resources