Django Signals to update a different model - django-signals

Say I have two models:
class Product(models.Model):
product = model.CharField()
quantity = model.IntegerField()
class sale(models.Model)
product = models.ManyToManyField(Product)
number_sold = model. IntegerField()
When a sale is made, I'd like the product quantity to be updated. Are signals the best way of going about this?
I was thinking about having sale admit a post_save signal when an object is created or updated. If updated, I would have to know the old and the new values to adjust the quantity properly. The product table would have to be listening for this signal.
I was also thinking about having the product table send a custom signal after it updates the quantity. If quantity < 0 item is on back order, else "success".
I am new to django and signals, but is this an appropriate use for signals or is their a better way to do this? I have read the docs, and watched a pycon video on signals, and read a few examples. I have yet to see signals used in this way, but I can't think of any other way to accomplish this task.
This is how I ended up accomplishing my goal, I am very interested to know if this is the proper way of doing this. I apologize for the models not matching the code below, I simplified my models to make it easier.
#receiver(pre_save, sender=Customer_Order_Products)
def update_quantity(sender, **kwargs):
obj = kwargs['instance']
updated_product = Inventory.objects.get(title = obj.product_id)
if not obj.id:
updated_product.quantity -= obj.quantity
else:
updated_product.quantity -= (obj.quantity - Customer_Order_Products.objects.get(id = obj.id).quantity)
Inventory.save(updated_product)

Related

What type of event or tool should I use to model customer orders using pre-existing data?

I am building a model where trucks leave main distributor to make deliveries to several customers along a route before returning back to the distributor when it is empty. I have been given pre-existing data in the form of a CSV of the exact location of all of the orders, the order weight, and how many orders there were at that location -- therefore, it's not a stochastic process that I'm modeling. My goal is to see how many deliveries the truck can make within 300 miles and a 20-hour round trip driving time, with the truck's total weight being decremented by the order weight at each stop. The initial truck capacity was 40,000 pounds.
Currently, I've created a standard "order" event, though I'm concerned my code is not correctly doing what I want it to. My order trigger type is "Timeout," mode is "cyclic," the first occurrence is 0.999 days, and the recurrence time is every 1 days. Below is my code on the "Action" module:
for( Truck truck: main.trucks){
double freeCapacity = truck.truckMaxCapacity - truck.truckCapacity;
if( distanceTo(truck, MILE) < 300 && totalWeight < freeCapacity && findFirst(main.trucks, tr->tr.customers.contains(this)) == null){
truck.customers.add(this);
truck.truckCapacity += totalWeight;
}
}
Since I'm not passing in the direct parameters of the orders in my code, I'm concerned the code I've written so far is generating orders rather than using what I already have. I have the order identification number, weight, and location all loaded in from a database within my "Customer" agent, which is also where the "order" event is located.
I'm new to StackOverflow, so thanks in advance for any help.

Meteor and MongoDB dropdown population and integrity

Hopefully I can describe this correctly but I come from the RDBMS world and I'm building an inventory type application with Meteor. Meteor and Mongodb may not be the best option for this application but hopefully it can be done and this seems like a circumstance that many converts will run into.
I'm trying to forget many of the things I know about relational databases and referential integrity so I can get my head wrapped around Mongodb but I'm hung up on this issue and how I would appropriately find the data with Meteor.
The inventory application will have a number of drop downs but I'll use an example to better explain. Let's say I wanted to track an item so I'll want the Name, Qty on Hand, Manufacturer, and Location. Much more than that but I'm keeping it simple.
The Name and Qty on Hand are easy since they are entered by the user but the Manufacturer and the Location should be chosen in a drop down from a data driven list (I'm assuming a Collection of sorts (or a new one added to the list if it is a new Manufacturer or Location). Odds are that I will use the Autocomplete package as well but the point is the same. I certainly wouldn't want the end user to misspell the Manufacturer name and thereby end up with documents that are supposed to have the same Manufacturer but that don't due to a typo. So I need some way to enforce the integrity of the data stored for Manufacturer and Location.
The reason is because when the user is viewing all inventory items later, they will have the option of filtering the data. They might want to filter the inventory items by Manufacturer. Or by Location. Or by both.
In my relational way of thinking this would just be three tables. INVENTORY, MANUFACTURER, and LOCATION. In the INVENTORY table I would store the ID of the related respective table row.
I'm trying to figure out how to store this data with Mongodb and, equally important, how to then find these Manufacturer and Location items to populate the drop down in the first place.
I found the following article which helps me understand some things but not quite what I need to connect the dots in my head.
Thanks!
referential data
[EDIT]
Still working at this, of course, but the best I've come up with is to do it normalized way much like is listed in the above article. Something like this:
inventory
{
name: "Pen",
manufacturer: id: "25643"},
location: {id: "95789"}
}
manufacturer
{
name: "BIC",
id: "25643"
}
location
{
name: "East Warehouse",
id: "95789"
}
Seems like this (in a more simple form) would have to be an extremely common need for many/most applications so want to make sure that I'm approaching it correctly. Even if this example code were correct, should I use an id field with generated numbers like that or should I just use the built-in _id field?
I've come from a similar background so I don't know if I'm doing it correctly in my application but I have gone for a similar option to you. My app is an e-learning app so an Organisation will have many Courses.
So my schema looks similar to yours except I obviously have an array of objects that look like {course_id: <id>}
I then registered a helper than takes the data from the organisation and adds in the additional data I need about the courses.
// Gets Organisation Courses - In your case could get the locations/manufacturers
UI.registerHelper('organisationCourses', function() {
user = Meteor.user();
if (user) {
organisation = Organisations.findOne({_id: user.profile.organisation._id});
courses = organisation.courses.courses;
return courses;
} else {
return false;
}
});
// This takes the coursedata and for each course_id value finds and adds all the course data to the object
UI.registerHelper('courseData', function() {
var courseContent = this;
var course = Courses.findOne({'_id': courseContent.course_id});
return _.extend(courseContent, _.omit(course, '_id'));
});
Then from my page all I have to call is:
{{#each organisationCourses}}
{{#with courseData}}
{{> admListCoursesItem}}
{{/with}}
{{/each}}
If I remember rightly I picked up this approach from an EventedMind How-to video.

Mahout: Recommending Items for a user in particular product category

What do we have as of now? - We are using Mahout's GenericItemBasedRecommender to get a list of recommended products for a user using TanimotoCoefficientSimilarity as ItemSimilarity.
Where do we want to go from here? - The above works fine when we don't care about product category but what we want to know is the Product Category specific recommendations i.e. Say if a user has been buying, browsing, liking etc. specifically more in Men's and Gadgets category, I would then want to show this user recommendation in that specific category saying Recommended for you in [X] where X would be replaced by Mens or Gadgets in this case. We are thinking about a couple of options below to achieve this and we need some leads/opinion/feedback etc. so as to make sure we are going in the right direction. Options:
Firstly we'll have to move to a non-tanimoto version for calculating item similarity so that we account for users buying, liking, etc and not only view/browsing data.
Figuring out product category for a particular user (this is where we need direction) - Our product category hierarchy is basically a tree and we need to know which top 4 nodes (with best recommendations) in tree we would show to the user. Also if we are saying that node X is a category which we are showing to the user and node Y is a parent of node X we then don't want show user products in category Y or any parent for that matter. Couple of ways achieving this:
For every user calculate SUM of similarity scores values of items for a nodes at leaf level and recursively calculate for parent node till the root. Now at each node we have A = SUM of similarity scores & B = Number of Items Recommended so we also have A/B=Value (V) at each node. Now we pick the top 4 V values from the tree and recommend that to the user. The challenge here is that if we try to calculate this online during the request it we would tough to limit this under 150 ms for the entire request. An Example:
Root Level - Category12 (A=11, B=4) (category1 + category2)
|
_____________________|_________________________
/ \
/ \
Leaf Level - category1 (A=6, B=2) category2 (A=5, B=2)
Recommended products in Category 1: Item1 (score = 2), Item2 (score = 4)
Recommended products in Category 2: Item3 (score = 1), Item4 (score = 4)
Second option: For every category create a cluster of users based on their behaviour (likes, buying, viewing etc.) and then figure out the top 4 categories to which the user belongs. Not sure if we can achieve this using clustering in Mahout but I think we can do this offline.
Please provide your feedback/suggestions/leads/thoughts.
Thanks in advance!
If you want to model more than one thing in your data, I would suggest to use the SVD recommender instead with the ALSWR factorizer set to implicit feedback. With that done you can have user,item,preference in your data and the preference value would be how strongly associated your user is to the item. You can play with the numbers, for example a purchase is a 20 and a view is just a 2. I'm just throwing numbers here, I wouldn't know what will work best for your data, because you can also model things proportionally, as in if a purchase is 30 times less likely to happen than a view, then a purchase should be 30 times stronger than a view.
Mahout provides a way to influence the recommendations through the IDRescorer. You implement your own logic here and decide how to affect the recommendations. For example, the IDRescorer would check if a recommendation candidate belongs to the same category and if it does, boost the score by X. There's an example here (link) from the Mahout in Action Book (which you should definitely read), showing a rescorer.
Hope this helps

Calculate Coredata result approach

Lets say I'm trying to RECORD as well as calculate results based on values stored in core data.
Lets take Enery equation : E=mc(square)
I have three entities, Parent/Child/RecentRecords
A Category's entity
Category
-Name : Einstein's equation
-E = mc2
Child Entity:
- Name: Mass
another entry:
- Name:LightSpeed (for the sake of example, lets say the speed of light is not constant.
Recent Entity: The purpose of this entity is to store and track the Child Entities and so it has:
-NSDate TimeStamp
-NSNumber: Value
-Relationship <---->>ChildEntity
I'll explain from a User's point of view,
If I tap "Einstain's equation" (Category/Parent Entity), the detail view will bring out 2 textfields by iterating through the Child entity. When I record my entries of mass, light speed, it should be saved in the Recent entity. SO that overtime i can have a bunch of recordings.
Now image a similar setup for another formula, v=U+at. where Velocity would be parent. U, a, t would be in CHild entity. And in one recording a user would add three Recent Entity objects.
My question is I want to find out if theres an efficient way to calculate the results/entries at the Parent/Category entity level.
Because, EinstainsEquation stores the formula of its child entities, E=mc2 and V=u+at. The thing thats making this complicated is fetching the entries from the recent Entity based on timestamp (recording) and calculating it and showing the result based on the most recent entries.
Parent<-------->>Child<-------->>Recent
-Einstein <---->>Mass <----------->>Multiple Mass recordings based on time
-mc2 LightSpeed <------>>Multiple Lighspeed records based on time
-Velocity<------>>U <--------->>Multiple entries based on time of all 3.
-u+at Aceleration
TimeTaken
Based on the graph above, I need to get einstein result FROM the most recent entries of mass/lightspeed and calculate each of those entries with its formula mc2.
I thought of having a transient Property in Parent entity, how would i go about accomplishing this? How can i use the formula and calculate the child values of recent entity.
I've read multiple tutorials but most of them have to do with basic setup.. I hope ill learn more each day

Satchmo: Specify delivery date/shipping date for an order

I working on e-commerce website using Satchmo. However, there are few customization required for my store.
While ordering a product I should be able to specify a delivery date (shipping date).
There can be only 20 (max_num_delievries) deliveries possible per day for a product. If number of deliveries for a particular date for a particular product exceeds 'max_num_delievries', user should not be able to select that date while ordering the product.
Can someone please help in this and guide me how to achieve this using Satchmo?
Thanks in advance..
I would try something like this:
1) create a local app (eg. delivery_date) with a model like "DeliveryDate" or so. For example localsite/delivery_date/models.py:
class DeliveryDate(models.Model):
product = models.ForeignKey(Product)
date = models.DateField()
order = models.ManyToManyField(Order)
class Meta:
unique_together = ("product", "date")
2) the validation of the max 20 existing orders... mhh, good question, maybe the best would be, to do it on the form? Override the clean method and check if this delivery date is associated with 20 orders already... maybe something like localsite/delivery_date/forms.py
class DeliveryDateForm(forms.ModelForm):
class Meta:
model = DeliveryDate
def clean(self):
super(DeliveryDateForm, self).clean()
... check here the order_set count
... but maybe the form isn't the best place to do this.
You also probably want to hide and auto-set the initial values for product and order yourself, and the user only being supposed to select a date.
3) Regarding satchmo... I would use signals to react after a product has been added to the cart (there is a signal just for this case), and add a listener which redirects the user to a view where he can select the date for this product. Look at the example here with the signal "cart_add_view": http://www.facebook.com/note.php?note_id=101466134049
Maybe ajax would be a good option here. With a hidden container in your page... which shows up after adding a product to the cart (only if the product hasn't already a DeliveryDate associated to this order/product), and asking the user to select a date.
This whole stuff would be on the listener: check if the product needs a delivery date, and if yes, send an ajax response to pop-up the window, and put in the repsonse-context the form, with the initial product and order hidden fields.
And to save the delivery-date you will need another ajax-view.
Well it's merely an idea how I would try to do it ;-) It will probably need adjustments here and there, of course. But hopefully it helps you further.
Regards,
Andrea