Web2Py list:reference table, Load and set data - reference

Maybe I'm missing something absurd, I'm not seeing, but this is my first app to study web2py.
I am unable to enter the data in Table Movies, which has fields related to other tables.
The list is loaded, but it is not registered in Movies registration.
Under the codes and the results.
db.py
Movie = db.define_table('movies',
Field('title','string', label = 'Title'),
Field('date_release','integer', label = 'Date Release'),
Field('duraction','integer', label = 'Duraction'),
Field('category','string','list:reference categories', label = 'Category'),
Field('actor','list:reference actors', label = 'Actor'),
Field('director','list:reference directors', label = 'Diretor'),
)
Category = db.define_table('categories',
Field('title','string', label = 'Title'),
)
validators.py
Movie.title.requires = [IS_NOT_EMPTY(), IS_NOT_IN_DB(db, 'movies.title')]
Movie.category.requires = IS_IN_DB(db, 'categories.title')
Movie.director.requires = IS_IN_DB(db, 'directors.name')
Movie.actor.requires = IS_IN_DB(db, 'actors.name')
Movie.duraction.requires = IS_INT_IN_RANGE(0, 1000)
Category.title.requires = IS_NOT_EMPTY()
movie.py
def add():
form = SQLFORM(Movie)
if form.process().accepted:
response.flash = "Successful! New movie added!"
redirect(URL('add'))
elif form.errors:
response.flash = 'Error'
else:
response.flash = 'Form, set data'
return dict(form = form)
List Load another tables - ok:
The items of list not record in DB:

The widgets displayed in the form are based on the IS_IN_DB field validators you have specified, and there are three problems with the way you have coded them.
First, list:reference fields, like standard reference type fields, store the record IDs of the records they reference -- they do not store values of other fields within the referenced records. So, the second argument to the IS_IN_DB validator should always be the ID field (e.g., categories.id).
Second, although the field will store record IDs, you want the form widget to show some other more descriptive representation of each record, so you should specify the "label" argument of the IS_IN_DB validator (e.g., label='%(title)s').
Third, list:reference fields allow for multiple selections, so you must set the "multiple" argument of the IS_IN_DB validator to True. This will result in a multi-select widget in the form.
So, the resulting validator should look like this:
Movie.category.requires = IS_IN_DB(db, 'categories.id', label='%(title)s', multiple=True)
The above will allow multiple db.categories IDs to be selected, though the form widget will display category titles rather than the actual IDs.
Now, all of the above can be made much easier if you instead define the referenced tables before the db.movies table and specify a format argument for each table:
Category = db.define_table('categories',
Field('title','string', label = 'Title'),
format='%(title)s')
Movie = db.define_table('movies',
...,
Field('category', 'list:reference categories', label = 'Category'),
...)
With the above code, there is no need to explicitly specify the IS_IN_DB validator at all, as the db.movies.category field will automatically get a default validator exactly like the one specified above (the format attribute of the db.categories table is used as the label argument).
You might want to read the documentation on list:reference fields and the IS_IN_DB validator.
As an aside, you might consider specifying your field validators within the table definitions (via the requires argument to Field()), as this is more concise, keeps all schema-related details in one place, and eliminates the need to read and execute an additional model file on every request.

Related

How does sibling or siblingAtRow() function works to retrieve the value from hidden Column in QTableWidget?

I have a database from which data is coming into a QTableWidget. The table in the database has the following Columns,
ID (Primary key, auto-increment value)
Name
Location
The QTableWidget has the following columns (that I have added)
ID (this column, I have hidden. and it contains the value of "ID" column from the Database Table)
Sr # (Represents the Row Number of the table)
Name (Contains "name" from the database table)
Location (Contains "Location from the database table)
Actions (Contains a Delete Button for that Row)
By hidden, I mean to say that I have made this column hidden using the folliwng command,
self.ui.table.setColumnHidden(0, True);
This is how I am populating my QTableWidget and creating a Delete Function,
def get_data(self):
mycursor = self.DB.cursor()
Subquery = "select id, name, location "
Subquery += " from tbl_person"
mycursor.execute(Subquery)
numcols = len(mycursor.fetchall()[0])
mycursor.execute(Subquery)
numrows = len(mycursor.fetchall())
self.ui.table.setRowCount(numrows)
self.ui.table.setColumnCount(numcols+2)
mycursor.execute(Subquery)
tablerow = 0
for row in mycursor.fetchall():
layout = QHBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)
delete_button = QPushButton("Delete Data")
delete_button.clicked.connect(self.executeDeleteFunction)
# delete_button.setStyleSheet(delete_push_button) -> Only for styling
self.ui.table.setItem(tablerow, 0, PySide2.QtWidgets.QTableWidgetItem(str(row[0])))
self.ui.table.setItem(tablerow, 1, PySide2.QtWidgets.QTableWidgetItem(str(tablerow+1)))
self.ui.table.setItem(tablerow, 2, PySide2.QtWidgets.QTableWidgetItem(str(row[1])))
self.ui.table.setItem(tablerow, 3, PySide2.QtWidgets.QTableWidgetItem(str(row[2])))
self.ui.table.setCellWidget(tablerow, 4, delete_button)
tablerow += 1
self.ui.table.setColumnHidden(0, True)
#self.ui.registered_table.horizontalHeader().setSectionResizeMode(PySide2.QtWidgets.QHeaderView.Stretch)
self.ui.table.resizeColumnsToContents()
def executeDeleteFunction(self):
self.person_id = self.ui.table.selectionModel().selectedIndexes()[0]
self.person_id = self.person_id.row()
mycursor = self.DB.cursor()
sql = "delete from tbl_person where id = %s"
val = (id, )
mycursor.execute(sql, val)
print("Deletion Successful")
On the Deletion Function, what this code does is basically gets the value of the **Sr # ** Column from the QTableWidget and deletes the data according to that, i.e. it is getting me the value from the visible first column and not the actual first column. But, I want the data from the "ID" column of the QTableWidget which is hidden
I tried to look up on how to get the value from the first hidden column on the QTableWidget and ended up with this link: How to get data from hidden 'id' column in QtableWidget
This apparently solves my issue but I can not seem to make it work for my code. I don't want to retrieve values of multiple Rows but only of one row so how do I do this (as I am only deleting one row. But in the question mentioned, I believe that it is getting data from multiple rows due to that for each loop)?
Moreover, I tried to find help regarding the functionality of sibling function (which is provided in the answer of above question) however I could not find any good resource on this function (i.e. how to use this, or some practical example and etc.)
I tried the following with Sibling function to obtain the value of first hidden column of the Selected Row but it did not work,
self.value = self.table.selectedItems()[0]
self.value = sibling(self.value.row(), 0)
There are some conceptual problems with the given code.
First of all, the QtSql module should be preferred instead of artificially creating a model. For basic tables, QSqlTableModel is fine enough, while for custom queries, QSqlQueryModel is a good choice.
Now the problem is that UI-based selection is always based on visible items: if you select a row in a view that has hidden columns, you will not get the hidden indexes that belong to those columns.
In order to get the indexes (as in QModelIndex) of hidden columns on a table widget, the only way is the same for a table view: you need to access the model and get the index for the row, or you get the actual model index and then get the sibling (which is conceptually the same, as the underlying function does):
item = self.table.selectedItems()[0]
index = self.table.indexForItem(index)
firstRowIndex = index.sibling(index.row(), 0)
sqlIndex = firstRowIndex.data() # might be a string
Note that you can also use siblingAtColumn():
firstRowIndex = index.siblingAtColumn(0)
That's because when you create QTableWidget items, you're actually creating a new model, and the row for that model doesn't reflect the actual "row" of that index in the source model; items in the second row will return 1 for row(), even if their actual row is different, and that's because that item has been added as second to the table widget, since it's the second item in the query.
So, the solution is that you either get the incremental row value for the first column index sibling, or you use one of the predefined Sql models.
For simple models, the latter solution is fine enough, but if you need more complex models, the first is certainly more accurate and reliable.

Android Studio Room query to get a random row of db and saving the rows 2nd column in variable

like the title mentions I want a Query that gets a random row of the existing database. After that I want to save the data which is in a specific column of that row in a variable for further purposes.
The query I have at the moment is as follows:
#Query("SELECT * FROM data_table ORDER BY RANDOM() LIMIT 1")
fun getRandomRow()
For now I am not sure if this query even works, but how would I go about writing my function to pass a specific column of that randomly selected row to a variable?
Ty for your advice, tips and/or solutions!
Your query is almost correct; however, you should specify a return type in the function signature. For example, if the records in the data_table table are mapped using a data class called DataEntry, then the query could read as shown below (note I've also added the suspend modifier so the query must be run using a coroutine):
#Query("SELECT * FROM data_table ORDER BY RANDOM() LIMIT 1")
suspend fun getRandomRow(): DataEntry?
If your application interacts with the database via a repository and view model (as described here: https://developer.android.com/topic/libraries/architecture/livedata) then the relevant methods would be along the lines of:
DataRepository
suspend fun findRandomEntry(): DataEntry? = dataEntryDao.getRandomRow()
DataViewModel
fun getRandomRecord() = viewModelScope.launch(Dispatchers.IO) {
val entry: DataEntry? = dataRepository.findRandomEntry()
entry?.let {
// You could assign a field of the DataEntry record to a variable here
// e.g. val name = entry.name
}
}
The above code uses the view model's coroutine scope to query the database via the repository and retrieve a random DataEntry record. Providing the returning DataEntry record is not null (i.e. your database contains data) then you could assign the fields of the DataEntry object to variables in the let block of the getRandomRecord() method.
As a final point, if it's only one field that you need, you could specify this in the database query. For example, imagine the DataEntry data class has a String field called name. You could retrieve this bit of information only and ignore the other fields by restructuring your query as follows:
#Query("SELECT name FROM data_table ORDER BY RANDOM() LIMIT 1")
suspend fun getRandomRow(): String?
If you go for the above option, remember to refactor your repository and view model to expect a String instead of a DataEntry object.

How to get source list types of particular list/record field?

Here is I have two entity custom fields with list/record type,
custom_dev_j15 entity field has a custom source list (eg: one, two, three, four, etc)
custom_qa_v93 entity field has a standard source list as an object (eg: customer )
I've two vendor entity custom fields as stated in screenshots of question,
custentity473 --> customer is selected as list source
custentity474 --> custom_dev_j15_m_list as selected as list source ( which is custom list)
Here is snippet that i used to get the options of these fields,
// Snippet
var fieldDetails = {};
var record = nlapiCreateRecord("Vendor");
var field = record.getField("custentity473");
var selectoptions = field.getSelectOptions();
for ( var i in selectOptions) {
var Option = {
id : selectOptions[i].getId(),
label : selectOptions[i].getText()
}
Options.push(Option);
}
fieldDetail["options"] = Options;
But my need is to get source list information like name of the list source (customer or custom_dev_j15_m_list) via suitescript
any idea on how to get this information?
Thanks in advance
I'm not sure I understand this question for what you're trying to do.
In NetSuite almost always, you accommodate to the source list types because you know that's the type, and if you need something else (e.g. a selection which is a combination/or custom selection you'll use a scripted field)
Perhaps you can expand on your use case, and then we can help you further?

Populating custom table on Shipment release

I have created a custom table and made it available on the Customers screen called 'Serial Tracking'. The purpose of this screen is to track serialised items that each customer is in possession of (regardless of who the item was purchased from).
I would like a record automatically added to the table on shipment release. I have attempted to customise the Release method of SoShipmentEntry but am having trouble getting all the required data together as well as the best way to structure the code.
The custom table DAC is
AUSerialTrack
Not necessarily the answer to your question but to long for a comment.
As an alternative, what if you set your Serials tab view to the Ship Line Split table without dealing with a custom table. You could get the information you needed with something like this: (need to convert to your BQL view for your serials tab)
SELECT [ship].[CustomerID],
[ship].[ShipmentNbr],
[split].[InventoryID],
[split].[LotSerialNbr]
FROM [dbo].[SOShipLineSplit] split
INNER JOIN [dbo].[SOShipLine] line
ON [line].[CompanyID] = [split].[CompanyID]
AND [line].[ShipmentNbr] = [split].[ShipmentNbr]
AND [line].[LineNbr] = [split].[LineNbr]
INNER JOIN [dbo].[SOShipment] ship
ON [ship].[CompanyID] = [split].[CompanyID]
AND [ship].[ShipmentNbr] = [split].[ShipmentNbr]
INNER JOIN [dbo].[InventoryItem] i
ON [i].[CompanyID] = [split].[CompanyID]
AND [i].[InventoryID] = [split].[InventoryID]
INNER JOIN [dbo].[INLotSerClass] c
ON [c].[CompanyID] = [i].[CompanyID]
AND [c].[LotSerClassID] = [i].[LotSerClassID]
WHERE [c].[LotSerTrack] = 'S'
AND [ship].[Confirmed] = 1;
Then when the user goes to the tab its always the current results. No custom code to fill in a custom table so easier for upgrades/customization maintenance.

How to get many to many values and store in an array or list in python +django

Ok
i have this class in my model :
i want to get the agencys value which is a many to many on this class and store them in a list or array . Agency which store agency_id with the id of my class on a seprate table.
Agency has it's own tabel as well
class GPSpecial(BaseModel):
hotel = models.ForeignKey('Hotel')
rooms = models.ManyToManyField('Room')
agencys = models.ManyToManyField('Agency')
You can make it a bit more compact by using the flat=True parameter:
agencys_spe = list(GPSpecial.objects.values_list('agencys', flat=True))
The list(..) part is not necessary: without it, you have a QuerySet that contains the ids, and the query is postponed. By using list(..) we force the data into a list (and the query is executed).
It is possible that multiple GPSpecial objects have a common Agency, in that case it will be repeated. We can use the .distinct() function to prevent that:
agencys_spe = list(GPSpecial.objects.values_list('agencys', flat=True).distinct())
If you are however interested in the Agency objects, for example of GPSpecials that satisfy a certain predicate, you better query the Agency objects directly, like for example:
agencies = Agency.objects.filter(gpspecial__is_active=True).distinct()
will produce all Agency objects for which a GPSpecial object exists where is_active is set to True.
I think i found the answer to my question:
agencys_sp = GPSpecial.objects.filter(agencys=32,is_active=True).values_list('agencys')
agencys_spe = [i[0] for i in agencys_sp]

Resources