How to get a single widget to set 2 fields in Django? - django

I got a model with 2 fields: latitude and longitude. Right now they're 2 CharFields, but I want to make a custom widget to set it in admin - was thinking about displaying Google Maps, then getting the coordinates of the marker.
But can I have 1 widget (a single map) to set 2 different fields?

Define lat and long fields on your form; set them to use the HiddenInputWidget.
After the init of your form, add another field which contains your custom widget that takes two values.
In the clean method for that added field, set the values of self.cleaned_data['lat'] and self.cleaned_data['lng']
There are probably cleaner ways, but it should work

I've used overriden full_clean method for data splitting. Using clean_FIELD method is too late.

I ended up setting a custom form on my admin with an extra not required field which had a widget that controls the map and setting a maps widget of that like stevejalim. However I didn't hide the input fields since they were still left in the view and I don't mind seeing them. It would probably be cleaner to override the template for editing that model instead and putting in a map, but that seemed like to much work for something that should be simple.
One solution would be if Django allowed for complex model fields where one model field corresponds to multiple db columns but that's not yet supported (see https://code.djangoproject.com/ticket/5929)
The other would be if Django would let us use a form field that corresponds to two model fields, but there doesn't seem to be a way of accomplishing that and I can't find a ticket for it.

Related

What is the most Django-appropriate way to combine multiple database columns into one model field?

I have several times come across a want to have a Django model field that comprises multiple database columns, and am wondering what the most Django way to do it would be.
Three use cases come specifically to mind.
I want to provide a field that wraps another field, keeping record of whether the wrapped field has been set or not. A use case for this particular field would be for dynamic configuration. A new configuration value is introduced, and a view marks itself as dependent upon a configuration value, redirecting if the value isn't set. Storing whether it's been set yet or not allows for easy indefinite caching of the state. This also lets the configuration value itself be not-nullable, and the application can ignore any value it might have when unset.
I want to provide a money field that combines a decimal (or integer) value, and a currency.
I want to provide a file field with a link to some manner of access rule to determine whether the request should include it/a request for it should succeed.
For each of the use cases, there exists a workaround, that in each case seems less elegant.
Define the configuration fields as nullable. This is undesirable for a few reasons: it removes the validity of NULL as a value for the configuration itself, so tristates and other use valid cases for NULL have to become a pair of fields or a different data type, or an edge case; null=True on the fields allows them to be set back to None in modelforms and the admin without writing a custom FormField for them every time; and every nullable column in a database is arguably bad design.
Define the field as a subclass of DecimalField with an argument accepting a string, and use that to contribute another field to the model. (This is what django-money does). Again, this is undesirable: fields are appearing "as if by magic" on the model; and configuring the currency field becomes not obvious.
Define the combined file+rule field instead as an entire model, and one-to-one to it from the model where you want to have the field. This is a solution to all use cases, but again comes with downsides: there's an extra JOIN required for every instance of the field - one can imagine a User with profile_picture, cv, passport, private_key etc.; there's an implicit requirement to .select_related(*fields) on every query that would ever want to access the fields; and the layout of the related model is going to have cold data interleaved with hot data all over the place given that it's reused everywhere.
In addition to solution 3., there's also the option to define a mixin factory that produces the multiple fields with matching names and whatever desired properties and methods. Again this isn't perfect because the user ends up with fields being defined in the model body, but also above that in the inheritance list.
I think the main reason this keeps sending me in circles is because custom Django model fields are always defined in terms of a single base field, because it's done by inheritance.
What is the accepted way to achieve this end?

Django Model become huge

In my project few models has many fields like more than 25. Like i have a model name PeriodOfStay. and it fields are like
date_of_entry
i94_number
port_of_entry
city ....etc (please check the image for all field)
also it has many boolean fields . in one form user can multiple options.
most of the fields are optional.
so i am confused should i put all the fields in one model. Is it best practice. I don't want split one model to more and use OneToOne Relation cause in that case i need to break up many models cause most of the models in my project are like this also i need to send all data at once in a single request.
I just need to save data and show data to user. in some case i need to search by some field . Like in this form i need to search by i94_number.
Is using JsonField is ok for this problem cause i need to search & filter in some case.
I appreciate any help. Advance Thanks For Help.
Regarding your question about when to use one-to-one relations:
https://dba.stackexchange.com/a/15405
I think a JsonField is not what you want if you want to search & filter based on some fields. Keeping it in normal fields will make it faster
Some related resource that might be interesting: https://en.wikipedia.org/wiki/Database_normalization

Display modified data from QAbstractListModel in QTableView

I have a QAbstractListModel that has a bunch of custom objects stored in it, and you can access the different fields of the custom objects in the model by specifying a role (if this is an improper use of Qt roles let me know because I must be confused). I want to display this data in a user friendly QTableView. I can get things displaying using a proxy model, but the issue is I don't want to display the raw values, I want to display specific data derived from the raw data. So for instance, I don't want a column for both ItemA.foo and ItemA.bar, I want to display just ItemA.foo - ItemA.bar in a single column. And to add to that, I want the automatic update functionality you get with models where if either ItemA.foo or ItemA.bar change, I want the difference column to automatically update and recalculate.
I would think that the way to do this would be to use some kind of table proxy model that listens to the source model, and then populates its own fields with the values derived from the source model and listens for dataChanged() signals from the source model. Then you plug this proxy model in to a QTableView. But to me this sounds like something that should be done in a view. Or is this something that should be done by the delegate? I could even go so far as to do these calculations in the base model itself and add roles specific to these values that should be displayed in the table, but that sounds like I am really overloading the responsibilities of the model.
TLDR: How do you manipulate data from a model in a QTableView? Should I do the data manipulation in the base model and then send that to the QTableView? Should I use a proxy model that manipulates the base data and sends it to the QTableView? Or am I completely misunderstanding something?
and you can access the different fields of the custom objects in the model by specifying a role
If you look at the documentation for Qt::ItemDataRole, you would see that Qt models should indeed provide different data for different roles but each role means some distinguished purpose of the data corresponding to the role. For example, the most commonly used role is probably Qt::DisplayRole as the data for this role defines the content displayed in the view e.g. it's the text in the table cell. If you are satisfied with all the other aspects of the view - font, background etc - you can just return empty QVariant for corresponding roles from your model, the view would figure out these details on its own. If you are using roles as a substitute for columns i.e. to return different pieces of conceptually the same data item, it is probably not the intended use of roles.
For the other part of your question - you can customize the appearance of data displayed in the view through the use of a delegate. For example, you could subclass QStyledItemDelegate, override its displayText method to display ItemA.foo - ItemA.bar instead of just ItemA.foo and then set this delegate into the column of your view corresponding to ItemA.foo via setItemDelegateForColumn. The tricky part here would be to detect changes in both ItemA.foo and ItemA.bar columns which would affect the text displayed in the delegate. A while back I implemented a dedicated class in one of my projects which listens to changes in some column of the original model and "reroutes" the change into another column through signal emitting. I did it to solve this very issue - to catch changes in what delegate should display although technically another model column is affected into which the delegate is not set.

Ordering models using Django AutoField with custom step size

Consider a model Section that is displayed on a site and created / edited by a user using the Django admin interface. I would like to add a field that allows the user to easily control the order in which sections are displayed on the site. The easiest option seems to be to allow for an integer field that is auto-incremented but can be edited by the user -- akin to what the built-in AutoField does.
However, to make editing the order easier, I would like to increment the fields default value by 10 every time, to allow the user to shift sections around more easily. The first section would get order=1, the next one order=11 and so on, that way a section can be wedged in between those first two by giving it, e.g., order=6.
Is there a way I can reuse AutoField to achieve this purpose? And if no, how could I best achieve this type of ordering scheme?
Ideally, what I'd like to achieve should look like this:
from django.db import models
class Section(models.Model):
text = models.TextField()
order = AutoField(step=10)
class Meta:
ordering = ('order',)
Autofield won't work. Not editable, needs to be primary key.
I also suggest to solve this visually using drag and drop in the UI and then reorder all sections within the whole, rather then allow wedging. If two people at the same time wedge 25 within 20 and 30, you still have the same problem. Reordering on save is a much cleaner solution, especially when using select_for_update:
Returns a queryset that will lock rows until the end of the transaction, generating a SELECT ... FOR UPDATE SQL statement on supported databases.

A django field with two fields. Need opinion

There is a scenario where I want to store two types of information for a field. For example, consider a field namely "name". This field should two types of the following information:-
Boolean - to store whether the user wants this field to be shown or not.
Label - if the user wants to change the label to show.
I was wondering to solve this by using a model. Any suggestions?
You can define fields on other model and use them with genericForeignKey