Reputation: 4170
For people from the future. I have scrapped tastypie and had success using Django-Rest-Framework and itertools as was suggested in the approved answer to this question.
I have a 2 models I want to link the results on as they're associated by a FK.
I've made the class in my API.py as follows -
class JobmstResource(ModelResource):
jobdtl_id = fields.ForeignKey(JobdtlResource, 'jobdtl_id')
class Meta:
jobdtlquery = Jobdtl.objects.using('Admiral').all()
jobmstquery = Jobmst.objects.using('Admiral').all()
queryset = chain(jobdtlquery, jobmstquery)
resource_name = 'Jobmst'
I then hit my api from the URL calling an ID (common ID in both queries).
http://localhost:8080/api/jobmst/3296/?format=xml
When I run it it fails complaining about -
'itertools.chain' object has no attribute 'model'
It seems django has no clean and clear way to do inner joins when you want results from more than 1 model so curious where the break is? Should I be attacking this differently.
If I view the query from a simple HTML it is displaying the results but does separate the values into the 2 models fields and all.
I want the values to display as if from 1 model.
Here is the models.py for the 2 models in question -
class Jobdtl(models.Model):
jobdtl_id = models.IntegerField(primary_key=True)
jobdtl_cmd = models.TextField(blank=True)
jobdtl_envfile = models.TextField(blank=True)
jobdtl_retnsn = models.SmallIntegerField(blank=True, null=True)
jobdtl_allowadhoc = models.CharField(max_length=1, blank=True)
jobdtl_waitop = models.CharField(max_length=1, blank=True)
jobdtl_fromdt = models.DateTimeField(blank=True, null=True)
jobdtl_untildt = models.DateTimeField(blank=True, null=True)
jobdtl_fromtm = models.DateTimeField(blank=True, null=True)
jobdtl_untiltm = models.DateTimeField(blank=True, null=True)
jobdtl_proxy = models.ForeignKey('Usrmst', db_column='jobdtl_proxy', related_name='Jobdtl_jobdtl_proxy',blank=True, null=True)
jobdtl_proxy2 = models.ForeignKey('Usrmst', db_column='jobdtl_proxy2', related_name='Jobdtl_jobdtl_proxy2',blank=True, null=True)
jobdtl_interval = models.SmallIntegerField(blank=True, null=True)
jobdtl_intervalcnt = models.SmallIntegerField(blank=True, null=True)
jobdtl_unit = models.CharField(max_length=1, blank=True)
jobdtl_duration = models.IntegerField(blank=True, null=True)
jobdtl_concur = models.SmallIntegerField(blank=True, null=True)
jobdtl_priority = models.SmallIntegerField(blank=True, null=True)
jobdtl_minrun = models.IntegerField(blank=True, null=True)
jobdtl_maxrun = models.IntegerField(blank=True, null=True)
jobdtl_failalarm = models.CharField(max_length=1, blank=True)
nodmst_id = models.ForeignKey('Nodmst', db_column='Nodmst_id', related_name='Jobdtl_Nodmst_id', blank=True, null=True)
nodlstmst_id = models.ForeignKey('Nodlstms', db_column='Nodlstmst_id', related_name='Jobdtl_Nodlstmst_id',blank=True, null=True)
jobdtl_inhevent = models.CharField(max_length=1, blank=True)
jobdtl_inhoptions = models.CharField(max_length=1, blank=True)
jobdtl_inhagent = models.CharField(max_length=1, blank=True)
jobdtl_inhrepeat = models.CharField(max_length=1, blank=True)
jobdtl_inhtime = models.CharField(max_length=1, blank=True)
jobdtl_timewin = models.SmallIntegerField(blank=True, null=True)
jobdtl_saveoutput = models.CharField(max_length=1, blank=True)
jobdtl_outputname = models.TextField(blank=True)
jobdtl_trackmethod = models.SmallIntegerField(blank=True, null=True)
jobdtl_trackcmd = models.TextField(blank=True)
jobdtl_deplogic = models.SmallIntegerField(blank=True, null=True)
jobdtl_rerun = models.CharField(max_length=1, blank=True)
jobdtl_params = models.TextField(blank=True) # This field type is a guess.
jobdtl_sapcount = models.IntegerField(blank=True, null=True)
jobdtl_normalexit = models.SmallIntegerField(blank=True, null=True)
jobdtl_normalrange = models.SmallIntegerField(blank=True, null=True)
jobdtl_normalop = models.SmallIntegerField(blank=True, null=True)
jobdtl_deprerun = models.CharField(max_length=1, blank=True)
jobdtl_carryover = models.SmallIntegerField(blank=True, null=True)
jobdtl_psjob = models.IntegerField(blank=True, null=True)
jobdtl_savelogonly = models.CharField(max_length=1, blank=True)
jobdtl_trxid = models.IntegerField(blank=True, null=True)
jobdtl_rerunok = models.CharField(max_length=1, blank=True)
jobdtl_workdir = models.TextField(blank=True)
jobdtl_extinfo = models.TextField(blank=True) # This field type is a guess.
servicemst_id = models.ForeignKey('Servicemst', db_column='Servicemst_id', blank=True, null=True)
jobdtl_estmethod = models.SmallIntegerField(blank=True, null=True)
jobdtl_nearoutage = models.SmallIntegerField(blank=True, null=True)
jobdtl_trackcl = models.CharField(max_length=1, blank=True)
jobdtl_statuscl = models.CharField(max_length=1, blank=True)
jobdtl_abrtonclderr = models.CharField(max_length=1, blank=True)
jobdtl_estdurexclude = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'jobdtl'
class Jobmst(models.Model):
jobmst_id = models.IntegerField(primary_key=True)
jobmst_type = models.SmallIntegerField()
jobmst_prntid = TreeForeignKey('self', null=True, blank=True, related_name='children', db_column='jobmst_prntid')
jobmst_active = models.CharField(max_length=1, blank=True)
evntmst_id = models.IntegerField(blank=True, null=True)
jobmst_evntoffset = models.SmallIntegerField(blank=True, null=True)
jobmst_name = models.TextField(db_column='jobmst_name', blank=True)
jobmst_mode = models.SmallIntegerField(blank=True, null=True)
jobmst_owner = models.ForeignKey('Owner', db_column='jobmst_owner', related_name = 'Jobmst_Jobmst_owner', blank=True, null=True)
jobmst_desc = models.TextField(blank=True) # This field type is a guess.
jobmst_crttm = models.DateTimeField()
jobdtl_id = models.ForeignKey('Jobdtl', db_column='jobdtl_id', blank=True, null=True)
jobmst_lstchgtm = models.DateTimeField(blank=True, null=True)
jobmst_runbook = models.TextField(blank=True) # This field type is a guess.
jobcls_id = models.IntegerField(blank=True, null=True)
jobmst_prntname = models.TextField(blank=True)
jobmst_alias = models.CharField(max_length=10, blank=True)
jobmst_dirty = models.CharField(max_length=1, blank=True)
class MPTTMeta:
order_insertion_by = ['jobmst_id']
class Meta:
managed = True
db_table = 'jobmst'
Upvotes: 0
Views: 707
Reputation: 6618
Because a ResourceModel is made to allow a REST client to make queries that filter, paginate and sort, which then trigger the appropriate SQL query, it's not possible to just use an iterator which cannot be as flexible.
Maybe you can hack something that works but looks like the cleanest stuff is to use a plain Resource and add your own logic. See this answer Tastypie: How can I fill the resource without database? which refers to Resource VS ModelResource in the documentation http://django-tastypie.readthedocs.org/en/latest/resources.html#why-resource-vs-modelresource
Upvotes: 0
Reputation: 9107
Have you tried converting itertools.chain
to a list:
queryset = list(chain(jobdtlquery, jobmstquery))
Update You can concatenate the queries on the same model like this:
queryset = query1 | query2
Update As the error message implies, your queryset has to have only one model
. You cannot achieve your goal with two different models.
This question seems like a dublicate.
Upvotes: 1