mercredi 13 août 2014

python - django combiner les requêtes sur deux modèles de base différents - Stack Overflow


I have two different different queryset, I want to make union of both queryset


 q1 = tbl_nt_123.objects.values_list('id', 'value', 'geometry').filter(restriction='height')\
.exclude(condition_id__in=tbl_conditions.objects.filter(version_id=5).values_list('condition_id',flat=True))

q2 = tbl_network.objects.all().filter(Q(name="height"), Q(state_id=1) | Q(state_id=2)).values_list('id', 'value', 'geometry');

I have tried this function



queryset = (q1) | (q2)



facing this error ' django combine queries on two different base models '


So i have tried two other functions but these are also throwing same exception ' list' object has no attribute 'model' '



queryset = list(q1) + list(q2)


queryset = chain(q1, q2)



Updating my question from here


class tbl_nt_123(models.Model):
condition_id = models.IntegerField(blank=True, null=True)
value = models.FloatField(blank=True, null=True)
geometry = models.GeometryField(blank=True, null=True)
class Meta:
db_table = u'tbl_nt_123'

class tbl_conditions(models.Model):
condition_id = models.IntegerField()
version_id = models.ForeignKey(LookupNavteqversion)
class Meta:
db_table = u'tbl_conditions'


class tbl_network(models.Model):
name = models.CharField(max_length=50, blank=True)
value = models.FloatField()
state_id = models.IntegerField(null=True, blank=True)
geometry = models.GeometryField(null=True, blank=True)
objects = models.GeoManager()

class Meta:
db_table = u'tbl_network'

def __unicode__(self):
return '%s' % self.name

class tbl_networkSerializer(serializers.GeoModelSerializer):
class Meta:
model = tbl_network
fields = ('id', 'value', 'geometry')

Here views file


   class NetworkViewSet(viewsets.ModelViewSet):

q1 = tbl_nt_123.objects.values_list('id', 'value', 'geometry').filter(restriction='height')\
.exclude(condition_id__in=tbl_conditions.objects.filter(version_id=5).values_list('condition_id',flat=True))

q2 = tbl_network.objects.all().filter(Q(name="height"), Q(state_id=1) | Q(state_id=2)).values_list('id', 'value', 'geometry');

queryset = list(chain(q1, q2))

serializer_class = tbl_networkSerializer

But both these functions did not return queryset type record.


I want queryset type of tbl_network (q2)


How can i do this?




As django doesn't support mixed querysets (they must correspond to just one model), I suggest you using a different approach: a model inheritance or FK.


class MyGeometry(models.Model):
value = ...
geometry = ...

class tbl_nt_123(MyGeometry):
condition_id = models.IntegerField(blank=True, null=True)
value = models.FloatField(blank=True, null=True)
geometry = models.GeometryField(blank=True, null=True)

class tbl_network(MyGeometry):
name = models.CharField(max_length=50, blank=True)
state_id = models.IntegerField(null=True, blank=True)
objects = models.GeoManager()

...
#you should also rewrite your queries and then merge them.
#remember that inheritance let's you access parent_links and children_links
#between models.
#your query 1 should be like this one below, and a similar approach for query2.
#since they will be of the same type, you can merge them. Later, you can access
#their children links ('tbl_nt_123' and 'tbl_network), being aware that upon non-existance those links will throw DoesNotExist, upon model iteration.

q1 = MyGeometry.objects.values_list('id', 'value', 'geometry').select_related('tbl_nt_123').filter(tbl_nt_123__restriction='height')\
.exclude(condition_id__in=tbl_conditions.objects.filter(version_id=5).values_list('condition_id',flat=True))

edit: don't know where did you get your 'restriction' field, since it does not appear in models, but i put it anyway to "respect" your code (assuming there's no error there).


edit 2: you can merge them with the methods you tried before, once the queries are of the same model (e.g. q1 + q2)



I have two different different queryset, I want to make union of both queryset


 q1 = tbl_nt_123.objects.values_list('id', 'value', 'geometry').filter(restriction='height')\
.exclude(condition_id__in=tbl_conditions.objects.filter(version_id=5).values_list('condition_id',flat=True))

q2 = tbl_network.objects.all().filter(Q(name="height"), Q(state_id=1) | Q(state_id=2)).values_list('id', 'value', 'geometry');

I have tried this function



queryset = (q1) | (q2)



facing this error ' django combine queries on two different base models '


So i have tried two other functions but these are also throwing same exception ' list' object has no attribute 'model' '



queryset = list(q1) + list(q2)


queryset = chain(q1, q2)



Updating my question from here


class tbl_nt_123(models.Model):
condition_id = models.IntegerField(blank=True, null=True)
value = models.FloatField(blank=True, null=True)
geometry = models.GeometryField(blank=True, null=True)
class Meta:
db_table = u'tbl_nt_123'

class tbl_conditions(models.Model):
condition_id = models.IntegerField()
version_id = models.ForeignKey(LookupNavteqversion)
class Meta:
db_table = u'tbl_conditions'


class tbl_network(models.Model):
name = models.CharField(max_length=50, blank=True)
value = models.FloatField()
state_id = models.IntegerField(null=True, blank=True)
geometry = models.GeometryField(null=True, blank=True)
objects = models.GeoManager()

class Meta:
db_table = u'tbl_network'

def __unicode__(self):
return '%s' % self.name

class tbl_networkSerializer(serializers.GeoModelSerializer):
class Meta:
model = tbl_network
fields = ('id', 'value', 'geometry')

Here views file


   class NetworkViewSet(viewsets.ModelViewSet):

q1 = tbl_nt_123.objects.values_list('id', 'value', 'geometry').filter(restriction='height')\
.exclude(condition_id__in=tbl_conditions.objects.filter(version_id=5).values_list('condition_id',flat=True))

q2 = tbl_network.objects.all().filter(Q(name="height"), Q(state_id=1) | Q(state_id=2)).values_list('id', 'value', 'geometry');

queryset = list(chain(q1, q2))

serializer_class = tbl_networkSerializer

But both these functions did not return queryset type record.


I want queryset type of tbl_network (q2)


How can i do this?



As django doesn't support mixed querysets (they must correspond to just one model), I suggest you using a different approach: a model inheritance or FK.


class MyGeometry(models.Model):
value = ...
geometry = ...

class tbl_nt_123(MyGeometry):
condition_id = models.IntegerField(blank=True, null=True)
value = models.FloatField(blank=True, null=True)
geometry = models.GeometryField(blank=True, null=True)

class tbl_network(MyGeometry):
name = models.CharField(max_length=50, blank=True)
state_id = models.IntegerField(null=True, blank=True)
objects = models.GeoManager()

...
#you should also rewrite your queries and then merge them.
#remember that inheritance let's you access parent_links and children_links
#between models.
#your query 1 should be like this one below, and a similar approach for query2.
#since they will be of the same type, you can merge them. Later, you can access
#their children links ('tbl_nt_123' and 'tbl_network), being aware that upon non-existance those links will throw DoesNotExist, upon model iteration.

q1 = MyGeometry.objects.values_list('id', 'value', 'geometry').select_related('tbl_nt_123').filter(tbl_nt_123__restriction='height')\
.exclude(condition_id__in=tbl_conditions.objects.filter(version_id=5).values_list('condition_id',flat=True))

edit: don't know where did you get your 'restriction' field, since it does not appear in models, but i put it anyway to "respect" your code (assuming there's no error there).


edit 2: you can merge them with the methods you tried before, once the queries are of the same model (e.g. q1 + q2)


0 commentaires:

Enregistrer un commentaire