I am building an advance search in django/angular where user can select one or more fields from different models
############# ############# #############
Model1 Model2 Model2
############# ############# #############
Field1 Field1 Field1
Field2 Field2 Field2
Field3 Field3 Field3
...... Fk(Model1) Fk(Model1)
....... ..........
Model2, Model3 and other models have foreignkey reference to Model1.
The selected models fields are send to the django views for further queries and result concatenation.
views.py
def customsearch(request):
queryrequest = json.loads(request.body)
result = []
print queryrequest
""" [{u'value': u'Field1', u'key': u'Model1'}, {u'value': u'Field2', u'key': u'Model2'}, {u'value': u'Field3', u'key': u'Model2'}, {u'value': u'Field2', u'key': u'Field2'}]"""
for item in queryrequest:
if(item['key'] == 'Model1'):
result.append(Model1.objects.filter().values(item['value']))
else:
result.append(item['key'].objects.filter().values(item['value']).select_related('fk'))
I have got a request of list of dictionaries. The list consist of key (model name) and value (field).
How can i make a queries and contenate results based on above example?
I am newbie to django!
Any helps and suggestions are welcome.
if your model2, model3 has fk to model1,
this is sample (you should use related_name for Model2, Model3 ForeignKey Field)
from django.db.models import Q
Model1.objects.filter(
Q(Field1=value1) &
Q(model2_related_name__Field2=value2) &
Q(model3_related_name__Field3=value3)
)
and, about related_name this
Related
model.py:
class Model1(models.Model):
#4 fields of type CharFieldvalues excepted from a user.
class Model2(models.Model):
field1 = models.OneToOneField(Model1, on_delete=models.CASCADE)
How can I create multiple entries of field1. The number of field1 could be 1 or 2 or more for each Model2 instance.
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.
I created a model class Parcel:
from django.db import models
from django.contrib.gis.db import models as gismodels
class Parcel(gismodels.Model):
new_pin = models.CharField(max_length=32)
geometry = gismodels.PolygonField(srid=32651)
objects = gismodels.GeoManager()
def __unicode__(self):
return self.new_pin`
Now, I want these model to have a joined query in other table(property), but these table(property) already existed in the database. Anybody knows how to implement it in python-geodjango?? Eventhough table(property) does not declared in my model.??How can I do it??
This is now the query I would like to display..
query in sql: (select t2.land_classification from table1 t1, table2 t2 where t1.new_pin = t2.new_pin group by t2.land_classification)
NOTE: Table 1 is the Parcel model above.
Table 2 is the existed table in the database.
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.
I am in a Model1 (Model1)and I need to run some business logic that should update a record in the Model2 (table2).
Here is the query/action I need to run from Model1 in Model2
$sql ="update table2 SET products = $product WHERE `id` = '".$id."'";
How would I go about doing it?
If the two models are related, you can save data to two tables at the same time. See the book for information on how to use Model::saveAll(). This is how you would represent that query though:
$this->Model2->id = $id;
$this->Model2->saveField('products', $product);
if the 2 models are not related (no relationship), Model->query() is a quick and dirty way. Otherwise, if Model1 has a relationship to Model2, in Model1, you can refer to Model2 by : $this->Model2->function_you_need_to_call()