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

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.

Related

Qt6: how to disable selection for empty cells in QTableView?

I'm trying to display some data from a database in a grid view, similar to how a file manager works. I thought of using a QTableView as the grid view since it did what I wanted out of the box. However, as shown with the below given MRE, even if just a single cell has value, you can still select the other empty cells, how can I prevent this? Basically, I want to make it so that only cells with a value can be selected.
MRE:
from PySide6 import QtWidgets as qtw
from PySide6 import QtGui as qtg
from PySide6 import QtCore as qtc
ROW_COUNT = 5
COL_COUNT = 5
class Model(qtc.QAbstractTableModel):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self._data = [[None for _ in range(COL_COUNT)] for _ in range(ROW_COUNT)]
def data(self, index: qtc.QModelIndex, role: qtc.Qt.ItemDataRole):
if not index.isValid():
return None
if role == qtc.Qt.ItemDataRole.DisplayRole:
return self._data[index.row()][index.column()]
return None
def setData(self, index: qtc.QModelIndex, value, role: qtc.Qt.ItemDataRole=qtc.Qt.ItemDataRole.DisplayRole):
if not index.isValid():
return False
if role == qtc.Qt.ItemDataRole.DisplayRole:
self._data[index.row()][index.column()] = value
return False
def rowCount(self, _):
return ROW_COUNT
def columnCount(self, _):
return COL_COUNT
app = qtw.QApplication()
view = qtw.QTableView()
view.setModel(Model())
view.setShowGrid(False)
view.verticalHeader().setVisible(False)
view.horizontalHeader().setVisible(False)
view.model().setData(view.model().createIndex(0, 0), "this is a test")
view.show()
app.exec()
You need to override the flags() and ensure that it doesn't return the ItemIsSelectable flag.
class Model(qtc.QAbstractTableModel):
# ...
def flags(self, index):
flags = super().flags(index)
if index.data() is None:
flags &= ~qtc.Qt.ItemIsSelectable
return flags
In your case, you also probably want to avoid the ItemIsEnabled, and since these two flags are the default one, you can just return NoItemFlags
def flags(self, index):
if index.data() is None:
return qtc.Qt.NoItemFlags
return super().flags(index)
If you also need to clear the selection, then you could subclass the view and do it in the mousePressEvent():
class TableView(qtw.QTableView):
def mousePressEvent(self, event):
index = self.indexAt(event.pos())
if index.isValid() and not index.flags() & qtc.Qt.ItemIsSelectable:
self.clearSelection()
else:
super().mousePressEvent(event)

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.

Tkinter not updating in Windows OS when scrolling too fast

As seen in the example above, a mixture of the Label objects on the left column or Entry objects on the right column are not shown when scrolling too fast.
If I click on the scrollbar and drag quickly it can look as bad as this. If I use the wheel on the mouse to scroll slowly it is typically fine, though sometimes a line will get missed no matter how slowly I scroll. For reference, it seems to always be the same line(s) that do not show when scrolling slowly.
Changing tabs back and forth causes everything to draw properly again. On Linux, everything works perfectly. But this needs to work on Windows as well.
Not sure if it matters, but each line is a Label and Entry inside of a Frame inside of a Canvas that, along with a Scrollbar, is inside of a Frame. Each of those top Frames is a "page" in a Notebook to provide the tabs shown on top.
And finally some questions. Is there a button I can add to force this to redraw without destroying and recreating it? Or possibly something I can add when creating these objects to force them to redraw when moved?
Sample code upon request:
#!/usr/bin/env python3
from tkinter import *
from tkinter import ttk
from tkinter.scrolledtext import ScrolledText
class WriteableEntry(Label):
def __init__(self, name, value, *args, **kwargs):
#~ self.ip = ip
#~ self.ping_results = []
super(WriteableEntry, self).__init__(*args, **kwargs)
self.label = name
self.init_value = value
self.written_value = ''
self.field_name = Label(self, justify="left", text=name, width=25)
self.field_value = Entry(self, justify='left', width=60)
self.field_value.insert(END, value)
self.field_name.pack(side=LEFT)
self.field_value.pack(side=LEFT)
class InfoFrame(Frame):
def __init__(self, *args, **kwargs):
super(InfoFrame, self).__init__(*args, **kwargs)
self.nb_frame = Frame(self, height=300, width=730)
self.nb_frame.pack_propagate(False)
self.nb = ttk.Notebook(self.nb_frame)
self.nb.pressed_index = None
filler = {}
for x in range(0, 3):
for y in ('a', 'b', 'c', 'd', 'e', 'f', 'g'):
filler.update({"out%d_%s" % (x, y):"nada"})
self.example_dict = {'A':filler, 'B':filler, 'C':filler}
print("E_D:\n", self.example_dict)
for page in sorted(self.example_dict):
print("page:\t", page)
entry_count = len(self.example_dict[page])
# # ## Make new_page to put in nb
new_page = Frame(self.nb)
new_page.pack(fill=BOTH, expand=True)
# # ## Make canvas to put in that new_page
canvas = Canvas(new_page)
scroll = Scrollbar(new_page, command=canvas.yview)
## Orig *27
canvas.config(yscrollcommand=scroll.set, scrollregion=(0,120,120,entry_count * 35))
canvas.pack(side=LEFT, fill=BOTH, expand=True)
scroll.pack(side=RIGHT, fill=Y)
# # ## Make a frame to put in that canvas
canvas_frame = Frame(canvas, bg='white', width=50, height=50)
## Orig +12 *10
canvas.create_window(345, (entry_count + 12) * 13, window=canvas_frame)
for value in sorted(self.example_dict[page]):
print("value:\t", value)
writeable_entry = WriteableEntry(value, self.example_dict[page][value], master=canvas_frame)
writeable_entry.pack(side=TOP)
self.nb.add(new_page, text=page)
self.nb.pack(side=TOP, expand=True, fill="both")
self.nb_frame.pack(side=RIGHT, expand=True, fill=BOTH)
class IPLabel(LabelFrame):
def __init__(self, *args, **kwargs):
super(IPLabel, self).__init__(*args, **kwargs)
self.info_frame = InfoFrame(master=self)
self.info_frame.grid(row=1, columnspan=2, sticky=E + W)
class AvailableApplication(Frame):
def __init__(self, master):
super(AvailableApplication, self).__init__(master)
#~ self.ips = ips
self.grid()
self.grid_propagate(True)
self.ip_widgets = []
self.createWidgets()
def createWidgets(self):
self.ip_frame = Frame(self)
self.ip_widgets = []
ip_widget = IPLabel(master=self.ip_frame)
ip_widget.grid(row=0, column=1, columnspan=4, sticky=E + W)
self.ip_widgets.append(ip_widget)
self.ip_frame.grid(row=1, column=0, columnspan=8)
self.ip_frame.grid_propagate(True)
if __name__ == "__main__":
root = Tk()
root.title("Example Script")
app = AvailableApplication(root)
app.mainloop()
root.destroy()
The main problem is the WriteableEntry. It is not a tk.Label. You can't have sub widgets (a tk.Label and a tk.Entry) of a tk.Label. You also have the wrong layout manager for this work. Maybe also because of the wrong sub widget use. You rely on the wrap behavior of the pack manager. Don't. Use the grid() manager.
For some reason tab C is not visible but that is another problem.
Using Ctrl-Tab I found that there is a third tab but the tab text was the empty string. Adding the tab with
self.nb.add(new_page, text="P"+page)
Made it better visible. I have no idea why the tab name "C" has a special meaning for tkinter
The only possible way to kill the App and window is by using the Close button. So why do you destroy the root window? It is already destroyed.
#!/usr/bin/env python3
from tkinter import *
from tkinter import ttk
from tkinter.scrolledtext import ScrolledText
class WriteableEntry(object):
def __init__(self, name, value, *args, **kwargs):
#~ self.ip = ip
#~ self.ping_results = []
#super(WriteableEntry, self).__init__(*args, **kwargs)
master = kwargs['master']
row = kwargs['row']
self.label = name
self.init_value = value
self.written_value = ''
self.field_name = Label(master, justify="left", text=name, width=25)
self.field_value = Entry(master, justify='left', width=60)
self.field_value.insert(END, value)
self.field_name.grid(row=row, column=0)
self.field_value.grid(row=row, column=1)
class InfoFrame(Frame):
def __init__(self, *args, **kwargs):
super(InfoFrame, self).__init__(*args, **kwargs)
self.nb_frame = Frame(self, height=300, width=730)
self.nb_frame.pack_propagate(False)
self.nb = ttk.Notebook(self.nb_frame)
self.nb.pressed_index = None
filler = {}
for x in range(0, 3):
for y in ('a', 'b', 'c', 'd', 'e', 'f', 'g'):
filler.update({"out%d_%s" % (x, y):"nada"})
self.example_dict = {'A':filler, 'B':filler, 'C':filler}
print("E_D:\n", self.example_dict)
for page in sorted(self.example_dict):
print("page:\t", page)
entry_count = len(self.example_dict[page])
# # ## Make new_page to put in nb
new_page = Frame(self.nb)
new_page.pack(fill=BOTH, expand=True)
# # ## Make canvas to put in that new_page
canvas = Canvas(new_page)
scroll = Scrollbar(new_page, command=canvas.yview)
## Orig *27
canvas.config(yscrollcommand=scroll.set, scrollregion=(0,120,120,entry_count * 35))
canvas.pack(side=LEFT, fill=BOTH, expand=True)
scroll.pack(side=RIGHT, fill=Y)
# # ## Make a frame to put in that canvas
canvas_frame = Frame(canvas, bg='white', width=50, height=50)
## Orig +12 *10
canvas.create_window(345, (entry_count + 12) * 13, window=canvas_frame)
for row, value in enumerate(sorted(self.example_dict[page])):
print("value:\t", value)
writeable_entry = WriteableEntry(value, self.example_dict[page][value], master=canvas_frame, row=row)
#writeable_entry.pack(side=TOP)
self.nb.add(new_page, text="P"+page)
self.nb.pack(side=TOP, expand=True, fill="both")
self.nb_frame.pack(side=RIGHT, expand=True, fill=BOTH)
class IPLabel(LabelFrame):
def __init__(self, *args, **kwargs):
super(IPLabel, self).__init__(*args, **kwargs)
self.info_frame = InfoFrame(master=self)
self.info_frame.grid(row=1, columnspan=2, sticky=E + W)
class AvailableApplication(Frame):
def __init__(self, master):
super(AvailableApplication, self).__init__(master)
#~ self.ips = ips
self.grid()
self.grid_propagate(True)
self.ip_widgets = []
self.createWidgets()
def createWidgets(self):
self.ip_frame = Frame(self)
self.ip_widgets = []
ip_widget = IPLabel(master=self.ip_frame)
ip_widget.grid(row=0, column=1, columnspan=4, sticky=E + W)
self.ip_widgets.append(ip_widget)
self.ip_frame.grid(row=1, column=0, columnspan=8)
self.ip_frame.grid_propagate(True)
if __name__ == "__main__":
root = Tk()
root.title("Example Script")
app = AvailableApplication(root)
app.mainloop()
#root.destroy()

Threading blocking GUI

I have a 2-way panel parsing a ListCtrl. I still have my GUI blocked from this thread:
class MyThread(threading.Thread):
def __init__(self, DirQ, new_dbfQ, RemoveQ):
threading.Thread.__init__(self)
self.DirQ = DirQ
self.new_dbfQ = new_dbfQ
self.RemoveQ = RemoveQ
def run(self):
""" worker """
self.OpenDir = self.DirQ.get()
self.new_dbf = self.new_dbfQ.get()
self.RegRemove = self.RemoveQ.get()
with open(str(self.OpenDir), 'r') as infile:
reader = csv.reader(infile)
data = StringIO()
writer = csv.writer(data)
for line in csv.reader(self.new_dbf.splitlines()):
row = line
row_edit = re.sub(self.RegRemove,'', row[1])
writer.writerow([row[0], row_edit])
msg = data.getvalue()
wx.CallAfter(Publisher().sendMessage, "update", msg)
I have a button the toggles:
def checkBtnClick3(self, event):
self.DirQ.put(self.OpenDir.GetValue())
self.new_dbfQ.put(self.new_dbf)
self.RemoveQ.put(self.RegRemove.GetValue())
t = MyThread(self.DirQ, self.new_dbfQ, self.RemoveQ)
t.setDaemon(True)
t.start()
Do I need to add some kind of idle function on my frame class to free-up the GUI?

local variable 'form' referenced before assignment

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'.

Resources