This is maybe a poor way to ask this question, as I haven't yet tried anything since I'm not sure if it's even possible without a bunch of custom JS added to the admin.
Given a model such as:
class MyModel(models.Model):
sku = models.CharField('SKU', max_length=20, primary_key=True)
bar_code = models.ImageField(upload_to='images/barcodes')
I want the user to select an image which will be a photo of a product's barcode. The image then needs to be processed to scan for the barcode (I'm using pyzbar) and this value should be saved to the primary key field sku.
Since I can't save the model without a primary key, and I need to upload the image field to scan the barcode to discover the value to be used for the primary key, I'm thinking that the only way to do this would be to use some client side JS in the admin to upload the image to a temp location using a DRF endpoint (or similar), read the barcode and return that value to the client which could then set the value of sku with some basic javascript. Then the model can be saved and image uploaded (a second time).
Is there a more straightforward way to do this in Django without adding my own client side JS to the admin and having to upload the photo twice?
Aside from the primary key, which may complicate things - you can extend ImageField and see how it populates its width and height columns, then do the same for the pyzbar generated barcode. See the update_dimension_fields for inspriation:
Update field's width and height fields, if defined.
This method is hooked up to model's post_init signal to update
dimensions after instantiating a model instance. However, dimensions
won't be updated if the dimensions fields are already populated. This
avoids unnecessary recalculation when loading an object from the
database.
Dimensions can be forced to update with force=True, which is how
ImageFileDescriptor.set calls this method.
You would add a method to do the work for pyzbar and then connect the signal in the same way.
Related
I am looking for a way to have a multiple choice field populated with choices made by a user. For example, they could have the following 3 entries: Yes, No, Unsure. I want a way to be translate this to a model.
I understand this can be done with pre-defined options using a CharField, or ChoiceField, but I haven't seen anything with "dynamic" data, such as user-generated data.
I think you shouldn't use choice fields in this case, because everytime a user creates a new option, you'll have to run a new migration.
Maybe you can create a UserOption model and create a new obj everytime a user creates a new option. Then fetch all the options the user has created when he needs to choose between them.
You can't apply user choices to a DB table. However, you could store a user's choices somewhere, such as a User's Profile, and use them in a dynamically constructed form with a ChoiceField to constrain what he can put into a particular database column / model field.
Could be a PITA if he decides to delete a choice and then wants to edit the (now invalid) data in one of his records.
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.
Assume that there is entity Product. Relation is set as follows:
Product --1:N--> ImageLink <--N:1-- Image
Such a setup is used to allow adding more info to the relation - who linked the image, when, etc. One of the attributes of ImageLink is also isMainImage (bool). That denotes that this one particular ImageLink contains the image we want to show as main image of the product.
When I want to set main image of the product I need to set all the ImageLinks to false except for the one I want to set as main. I retrieve the links from Product - $product->getImageLinks(). That will fetch all the ImageLinks entries from DB and convert them to objects. I will traverse over all of them and set the correct value for isMainImage. Then I flush the entity manager.
Someone could have added a new image and marked it as main image in the meantime. That image was not selected from DB and was not converted to object. So is was not set to false. It will therefore not be changed during the flush.
Now I have two main images. How do I solve this?
Without ORM I would update the images in one db query, something like UPDATE image_link SET is_main = IF(id = 13, 1, 0).
I'm currently implementing a solution using django admin, it allows users to define in the db a product, and then custom attributes and details, more details may be aggregated by a common attribute, this allows me to query with ajax a custom view that returns some JSON data to build automagically the form fields that I need directly in the same formset view (manipulating the DOM).
The current DB design follows this schema:
Catalog(name, description, photo)
Product(rel_catalog, name, base_price, photo, manufacturer_email)
ProductDetail(rel_product, rel_attribute, percentage_price, fixed_price)
ProductAttribute(rel_product, name, description)
As you may see I have a catalog, where there can be more products, a lot of details per product, aggregated by attributes. Then I simple show by default the Catalog, then the select with all available products for that catalog, then, choosing the right Product, I obtain the complete form (each row has a label with ProductAttribute.name and a select with related ProductDetail).
All works pretty dam good, but I also need to store this references in the DB when someone completes the form (making an order with choosen products). This forms are displayed as StackedInline (the ModelAdmin is for the Order).
I don't know how many options there may be per product so I was thinking to use this design to track orders:
Order(customer, status, notes, tot_price, inserted_by)
OrderItem(rel_order, catalog, product, unit_price)
But I don't know how to store the dynamic added inputs...
I was thiking to implement OrderItemProperty(rel_orderitem, rel_productdetail, rel_productattribute) to store each single input... but how do I loop over this unknown fields?
Maybe do you suggest a better design?
If you need more code just ask for it and I'll reply with a pastebin link.
Thankyou.
Finally I got a working solution,
I've created a custom view, overriding the default "add/" view, this way I can customize whatever I want to and I can read the POST data handling each validation, putting then the data in the right model.
I am a bit stuck on how I should model this out.
Here is what I have:
I have a model called Location. In this model I have postal code, city, region, longitude, and latitude. This data is pre-populated with all of Canada's stuff. You can imagine this table is quite large.
This is what I would like to achieve by stuck on how to model this:
I would like to create a second model called Item. Each one of these items will need to be tied to a location from the said above model. The user-story would be as follows:
User adds an item: I already know their postal code and city based on their cookie that I set.
User submits the form with their item: this is where I am confused as to how to model this data so that the item gets saved in the proper location.
I figured a FK would be the way to go but that is waaaaay to inefficient for a number of obvious reasons (huge list, and requires user input but I already know their location before saving). So, since I already know their location based on their cookie, should create a new field in the Item model called location and just save the postal code in this model? If I did this I guess I would have to query the location model for that location to pull in proper info. I am not sure what the best to go about this is, please help.
If you already know the user's location, and they're just entering an item, then the Item model should have a foreign key to Location, but you don't prompt for it on the form. Instead, fill in the Location before you save the item.
If you're using a ModelForm, then you'll want to exclude your location field so that it isn't displayed. You'll also want to set commit=False so that you can fill in the location yourself before saving the form data to the Item table.