On the one hand, i have three CollectionsView (three types of models fetched from the server), on the other hand i have a quarter CollectionView that works like a shopping cart. This stores items from the other three Collections associated with the views (Collections Views).
The problem is when i add a item with the same id this is edited, not added to the Shopping cart CollectionView.
Example:
function addToCart(model){
ShoppingCartCollectionView.collection.add(model);
}
From the others collections:
// From one CollectionView
addToCart(this.model);
// From another CollectionView
addToCart(this.model);
This Collections have the same id because they are stored in diferent databases on the server.
This is my model (Python ORM)
PRODUCT_TYPE = (
('EM', 'Empanada'),
('BE', 'Bebida'),
('OF', 'Oferta'),
)
# Create your models here.
class Producto(models.Model):
nombre = models.CharField(max_length=50)
precio_unidad = models.DecimalField(max_digits=8, decimal_places=2)
descripcion = models.TextField()
stock = models.IntegerField()
status = models.BooleanField(default=True)
imagen = models.ImageField(upload_to=upload_to)
fecha_publicacion = models.DateTimeField(auto_now_add=True)
class Meta:
abstract = True
class Empanada(Producto):
precio_docena = models.DecimalField(max_digits=8, decimal_places=2)
product_type = models.CharField(max_length=2, choices=PRODUCT_TYPE, default='EM', editable=False)
def __unicode__(self):
return self.nombre
class Bebida(Producto):
product_type = models.CharField(max_length=2, choices=PRODUCT_TYPE, default='BE', editable=False)
def __unicode__(self):
return self.nombre
class Oferta(Producto):
product_type = models.CharField(max_length=2, choices=PRODUCT_TYPE, default='OF', editable=False)
def __unicode__(self):
return self.nombre
class Venta(models.Model):
pedido = models.TextField()
total = models.DecimalField(max_digits=8, decimal_places=2)
status = models.BooleanField(default=True)
fecha_publicacion = models.DateTimeField(auto_now_add=True)
How to solve this?
THANKS !!!
#KimGysen is right about looking into restructuring your products tables. Having different products with the same id is going to cause you problems in the long run. Here's a database schema that may work for you.
Using foreign key tables
First you'd have a product name table where you'd list the name of your different products and assign each product type a primary key (ID). Then, group the different attributes of your product and make a separate table for each group. In the table you'd refer to your original product types by their ID (this is your foreign key). Here's a simple diagram:
/*Name Table Prod Type 1
------------------------------- ---------------------------------
| ID | Product Name | Prod Type | ProdId | attr1 | ... | attrN |
------------------------------- ---------------------------------
| 1 | Product 1 | 1 | | 1 | val1 | ... | valN |
------------------------------- ---------------------------------*/
Work with or around collection.set
Your other option is to override the collection.set method in Backbone, which is responsible for identifying whether there are duplicates in your set.
Cheating collection.set
If you're having problems because your adding two different types of products with the same id you can cheat collection.set by making sure that their id attribute is called something other than id (this is what set uses to evaluate whether you have to identical models in your collection, unless you tell it to check a different property by setting the idAttribute property in your model definition). Then collection.set will not know how to match incoming models.
Overriding collection.set
If you're having trouble because collection.set is not storing a model that is already in your collection, then you will have to override collection.set. Let me know if this is the fix you're looking for and I'll post that answer here.
Create a new ShoppingCart Model
A third possibility is to have a ShoppingCart model that handles the addition and removal of models. This is a more complicated solution. If you provide more details about how your cart is being used I can drop a few ideas on how to get your started.
Related
I am creating a tool where users can follow each other. The way I have Implemented this is by extending the user model in Django as people model.
here is the people Model ->
class People(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,related_name='people')
Name = models.CharField(max_length=255,null=True)
following = models.ManyToManyField(to=User, related_name='following', blank=True)
photo = models.ImageField(upload_to='profile_pics', blank=True,null=True)
Phone_number = models.CharField(max_length=255,null=True,blank=True)
Birth_Date = models.DateField(null=True,blank=True)
Created_date = models.DateTimeField(auto_now_add=True)
Updated_date = models.DateTimeField(auto_now=True)
Here the poeple model is extended from user model and the relation is defined using oneToOneField.
Now the following column has many to many relation to the user model.
The Schema of the people_following table is that is has 3 columns
ID -> unique Identified (Primary Key)
People_id = user that has been followed.
User_id = user who is following(Logged in user)
suppose user with ID = 2 is logged in and wants to follow the User with ID = 7
then following will be the row in the table ->
ID people_id user_id
1 7 2
Now I would like to count the no of followers and the no of people following a particular user(Logged In user)
here is the Query ->
user_id = pk
person = People.objects.select_related('user').get(user_id=user_id)
context = {
'followers': person.following.filter(people_id=user_id).count(),
'following': person.following.filter(user_id = user_id).count(),
}
But this is giving me error ->
cannot resolve keyword -> people_id.
can anyone help me out with this.
I am trying to get down through multiple-foreign key relationship where each Hotel has many Rooms, each Room has many Rateplans, each Rateplan has many Prices.
It resembles Christmas tree if you think about it:
Hotel
v
Room
v
Rateplan
v
Prices
How can I execute query that will return hotels in certain hotel_city on certain price_date, certain price_price and certain price_availability? (just like Expedia or booking.com query)
For example:
Hotel.objects.filter(city='Beirut').filter(room__name=Room.objects.filter(rateplan__name=Rateplan.objects.filter(prices__availability=Prices.objects.filter(availability=1))))
I have looked into django complex queries documentation and annotate/aggregate but couldn't wrap my head around it.
My models below:
class Hotel(models.Model):
name = models.CharField(max_length=64)
city = models.CharField(max_length=64, default='Warsaw')
class Room(models.Model):
hotel_id = models.ForeignKey(Hotel, on_delete=models.CASCADE, related_name='room')
name = models.CharField(max_length=64, default='Double')
class Rateplan(models.Model):
room_id = models.ForeignKey(Room, on_delete=models.CASCADE, related_name='rateplan')
name = models.CharField(max_length=64, default='Standard')
class Prices(models.Model):
rateplan_id = models.ForeignKey(Rateplan, on_delete=models.CASCADE, related_name='prices')
date = models.DateField()
price_1 = models.DecimalField(null=False, max_digits=7, decimal_places=2)
price_2 = models.DecimalField(null=False, max_digits=7, decimal_places=2)
availability = models.SmallIntegerField()```
You can use __ to filter the values you need across relationships
There are good examples in the documentation
Hotel.objects.filter(
city=your_city,
room__rateplan__prices__date=your_date,
room__rateplan__prices__price_1=your_price,
room__rateplan__prices__availability=your_availability,
).distinct()
I am new to Django framework, I am trying to build the following system which contains a user who follows multiple stocks and the stocks are followed by multiple people, I'm trying to create a composite key using an intermediate class, but I'm having this error.
class Stock(models.Model):
symbol = models.CharField(max_length=12, primary_key=True,default="")
name = models.CharField(max_length=64)
top_rank = models.IntegerField(null=True)
price = models.FloatField()
change = models.FloatField(null=True)
change_percent = models.FloatField()
market_cap = models.FloatField(null=True)
primary_exchange = models.CharField(null=True, max_length=32) # NASDAQ
followers = models.ManyToManyField('myapp.Users',through='Follow',through_fields=('u_id','s_id'))
class Users(models.Model):
user_id = models.IntegerField(primary_key=True,default="")
name = models.CharField(max_length=12)
class Follow(models.Model):
u_id=models.ForeignKey('Users',on_delete=models.CASCADE)
s_id=models.ForeignKey('Stock',on_delete=models.CASCADE)
myapp.Stock.followers: (fields.E339) 'Follow.s_id' is not a foreign key to 'Users'.
HINT: Did you mean one of the following foreign keys to 'Users': u_id?
myapp.Stock.followers: (fields.E339) 'Follow.u_id' is not a foreign key to 'Stock'.
HINT: Did you mean one of the following foreign keys to 'Stock': s_id?
The order of the through_fields [Django-doc] is incorrect. As specified in the documentation:
through_fields accepts a 2-tuple ('field1', 'field2'), where field1 is the name of the foreign key to the model the ManyToManyField is defined on (...), and field2 the name of the foreign key to the target model (...).
So that means the first item of the through_fields should be 's_id' here, since that refers to the Stock model, the model where you defined the ManyToManyField, and the second item should be 'u_id':
class Stock(models.Model):
# …
followers = models.ManyToManyField(
'myapp.Users',
through='Follow',
through_fields=('s_id','u_id')
)
That being said, you here do not need to define the through_fields here, since your Follow model contains exactly two ForeignKeys that point to different models. In fact you do not need to define a through=... model either, since it does not contain any extra fields.
Note that usually a ForeignKey does not contain an _id suffix, since Django will automatically add an extra field with the _id suffix that contains the primary key of the referenced value.
Therefore it might make more sense, to just define the models as:
class Stock(models.Model):
symbol = models.CharField(max_length=12, primary_key=True)
name = models.CharField(max_length=64)
top_rank = models.IntegerField(null=True)
price = models.FloatField()
change = models.FloatField(null=True)
change_percent = models.FloatField()
market_cap = models.FloatField(null=True)
primary_exchange = models.CharField(null=True, max_length=32) # NASDAQ
followers = models.ManyToManyField('myapp.User')
class User(models.Model):
user_id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=12)
Note that models usually have a singular name, so User, instead of Users.
Basically, I have issues working with a legacy database where the tables I am using have no proper referential integrity (like no foreign keys; just tables but 'I' know they are related by some columns). So, Django's framework would not be beneficial while querying n tables across m different oracle users.
Something like this:
select t1.col1, t2.col3, t3.col2 from user1.table1 t1, user2.table2 t2, user3.table3 t3 where t1.col1 = t2.col2 AND t2.col2 = t3.col3;
And now in Django's Admin UI, I wanted to display this:
---------------------------
| col1 | col3 | col2 |
---------------------------
| abcd | defg | hijk |
---------------------------
| 1234 | 5678 | 9009 |
---------------------------
I have started on Django for its fast development only very recently. Hence, any support or docs are much appreciated.
To take advantage of Django Admin, you need to make a model first, no matter from where it fetches data.
Now, since we are mapping the model to DB, you could either make the model based on a DB view, or any one of the three tables(user1.table1, user2.table2 and user3.table3):
Base on DB view:
First, create a DB view to take col1, col2 and col3 from tables.
Also, choose a primary key for the model: it could be any (including extra) column in the DB view, as long as the model field w/ primary_key=True matches the column, here I simply choose col1.
# use Sqlite to create view, Oracle could be similar
CREATE VIEW view_for_legacy_tables AS SELECT t1.col1, t2.col3, t3.col2 from user1.table1 t1, user2.table2 t2, user3.table3 t3 where t1.col1 = t2.col2 AND t2.col2 = t3.col3;
# in model
class Foo(models.Model):
col1 = models.TextField(primary_key=True)
col2 = models.TextField()
col3 = models.TextField()
class Meta:
db_table = 'view_for_legacy_tables'
From now on, syncdb or South migrate might complain the exists, here simply ignore them.
You could bypass it by faking migration in South or move the model from models.py to other files or functions that does not loaded by models.py.
After define corresponding ModelAdmin for the model Foo, the Foo could be displayed in changelist in Django Admin.
If you want to use addview or changeview to do some modification upon the tables, you could override save method of the Foo model or customize ModelForm, or customize add_view/change_view of the ModelAdmin. The code varies on your actual usage, thus I don't provide one here.
Base on table user1.table1
This works similar as the method based on DB view. To be able to use addview and changeview, you need to customize ModelForm also.
Define the model
class Foo(models.Model):
col1 = models.TextField(primary_key=True)
class Meta:
db_table = 'user1.table1'
Then in admin.py
class FooAdmin(admin.ModelAdmin):
list_display = ('col1', 'col2', 'col3')
def queryset(self, request): # you could customize the default manager of model Foo
qs = super(FooAdmin, self).queryset(request)
return qs.extra(select={'col2':'user2.table2.col2', 'col3':'user3.table3.col3'},
tables=['user2.table2', 'user3.table3'],
where=['col1 = user2.table2.col2', 'user2.table2.col2'='user3.table3.col3']) # or use `raw()`, depends on your columns
def col2(self, obj):
return obj.col2
def col3(self, obj):
return obj.col3
update
The usage is very uncommon, thus I've seen few documents about it. Most relative things could be options.py inside django/contrib/admin and the implementation of Model inside django/db/models/base.py.
If you want to achieve SELECT * from t1, t2, t3 where ... like '%?%'", [var1]), the easiest way probably is to write your own view by using Admin UI, just as https://github.com/dmpayton/django-mongoadmin
If var1 of SELECT * from t1, t2, t3 where ... like '%?%'", [var1]) is determined, you could make several models for each value of var1; if its not, you have to do some dynamic way about model and admin, just ref Django dynamic model fields , which could be even harder IMO.
The flow I am working on has
A Product Table, categorized using a Category Table
A Optional Items Table, listing options of the product master hierarchically.
Analogy - Consider a shopping cart with a hierarchical structure as follows -
Laptops & Computer Peripherals in the Category Table
Laptops in the Product Table
HP in the Optional Items Table, there can be many such options
HP Type A Parent in the Optional items Table
HP Type B Parent in the Optional items Table
HP Type B Child in the Optional items Table
HP Type C Super Parent in the Optional items Table
HP Type C Parent in the Optional items Table
HP Type C Child in the Optional items Table
Lenovo in the Optional Items Table in the Optional items Table
Sony in the Optional Items Table in the Optional items Table
Graphics Card in the Product Table
Mobiles in the Category Table
I have the following
models.py
class Product(models.Model):
productid = models.AutoField(primary_key=True)
productname = models.CharField(max_length=255, unique=True)
categoryid = models.ForeignKey(Categorytbl, db_column='CategoryID')
class Optionalitemstbl(models.Model):
optionid = models.AutoField(primary_key=True)
productid = models.ForeignKey(Product)
optionname = models.CharField(max_length=255, unique=True)
optionparentid = models.ForeignKey("self", related_name='+', blank=True, null=True)
def clean(self, *args, **kwargs):
if self.optionparentid and self.productid:
if self.optionparentid.optionid == self.optionid:
from django.core.exceptions import ValidationError
raise ValidationError('Option cannot be an option of itself')
return
super(Optionalitemstbl, self).save(*args, **kwargs)
This enables me to create relationships as in the analogy above.
However the issue is, it also allows circular relationships. Say if a user has made the listing as in the analogy above in the admin site, it is possible for him to also list HP Type C Child as a parent of HP or any of its other parent nodes in the table.
Please suggest -
Is this the right approach for the analogy mentioned?
If it is, what modifications will prevent such circular relationships?
Thanks !