Django中关联三个模型获取特定作者全部书籍字段方案咨询
解决Django中通过作者获取对应所有书籍字段的问题
我看了你现在的模型和视图代码,核心问题是还没把作者和书籍的关联查询打通,而且部分视图返回数据的方式也不对(比如直接返回QuerySet对象,不是序列化后的JSON)。下面给你两种可行的实现方案,你可以根据自己的情况选择:
方案一:基于现有模型结构,直接关联查询
首先,我们可以给Bookauth模型的外键添加related_name,让反向查询更直观(这一步可选,但能让代码更清晰):
class Bookauth(models.Model): bid = models.ForeignKey(Books, on_delete=models.DO_NOTHING, db_column='bid', blank=True, null=True, related_name='linked_authors') aid = models.ForeignKey(Authors, on_delete=models.DO_NOTHING, db_column='aid', blank=True, null=True, related_name='linked_books')
然后新建一个视图,用来根据作者ID获取他的所有书籍:
import json from django.core import serializers def get_author_all_books(request): # 获取前端传过来的作者ID author_id = request.GET.get('author_id', '') if not author_id.isdigit(): return HttpResponse(json.dumps({'error': '请传入有效的作者ID'}), content_type='application/json') try: # 直接通过跨表查询,找到该作者关联的所有书籍 target_books = Books.objects.filter(bookauth__aid__pk=author_id) # 序列化书籍的所有字段为JSON serialized_data = serializers.serialize('json', target_books) return HttpResponse(serialized_data, content_type='application/json') except Exception as e: return HttpResponse(json.dumps({'error': str(e)}), content_type='application/json')
调用这个视图的时候,只需要在URL里传?author_id=xxx就能拿到对应作者的所有书籍数据了。
方案二:改用Django的ManyToManyField优化关联
其实你的Bookauth本质就是一个多对多关联的中间表,Django原生支持这种场景,用ManyToManyField能让查询更简洁。我们可以修改Authors模型:
class Authors(models.Model): aid = models.AutoField(primary_key=True) aname = models.CharField(max_length=200, blank=True, null=True) adescription = models.TextField( blank=True, null=True) # 通过Bookauth中间表关联Books模型 books = models.ManyToManyField(Books, through='Bookauth', related_name='authors') def __str__(self): return self.aname
这样查询作者的书籍就变得非常简单,对应的视图可以写成:
import json from django.core import serializers def get_author_all_books(request): author_id = request.GET.get('author_id', '') if not author_id.isdigit(): return HttpResponse(json.dumps({'error': '请传入有效的作者ID'}), content_type='application/json') try: author = Authors.objects.get(pk=author_id) # 直接通过关联属性拿到所有书籍 target_books = author.books.all() serialized_data = serializers.serialize('json', target_books) return HttpResponse(serialized_data, content_type='application/json') except Authors.DoesNotExist: return HttpResponse(json.dumps({'error': '该作者不存在'}), content_type='application/json') except Exception as e: return HttpResponse(json.dumps({'error': str(e)}), content_type='application/json')
顺便提一下你现有视图的小问题
比如你的author_search和book_search视图,直接返回HttpResponse(auth)或者HttpResponse(book)是不对的,因为auth和book是QuerySet对象,直接返回会显示对象的字符串形式,不是前端需要的JSON数据,你应该像上面的代码一样用serializers.serialize处理后再返回。
内容的提问来源于stack exchange,提问作者l0n3_w01f
相关产品推荐
相关产品推荐

