英文:
Regroup many-to-many fields in django
问题
我要获取给定用户的所有UserExercises,然后在我的模板中按类别分组显示它们,所以如果我有:{Ex1: {category: ["C1", "C2"]}, Ex2: {category: "C2"}}
,我希望它们被重新排序如下:{"C1": ["Ex1"], "C2": ["Ex2", "Ex1"]}
英文:
I have these model relationships
class ExerciseCategory(models.Model):
owner = models.ForeignKey(get_user_model(), on_delete=models.SET_NULL, blank=True, null=True)
name = models.CharField(max_length=100)
class UserExercises(models.Model): #Through table for the many-to-many relationship between User and Exercise
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, related_name="user")
exercise = models.ForeignKey('Exercise', on_delete=models.CASCADE)
class Exercise(models.Model):
category= models.ManyToManyField(ExerciseCategory, through='CategoryExercisesThrough',blank=True, null=True)
assignee = models.ManyToManyField(get_user_model(), blank=True, null=True, through=UserExercises, related_name="assignee", through_fields=('exercise', 'user'))
class CategoryExercisesThrough(models.Model): #Through table for the many-to-many relationship between ExerciseCategory and Exercise
category= models.ForeignKey(ExerciseCollections, on_delete=models.CASCADE)
exercise = models.ForeignKey(Exercise, on_delete=models.CASCADE)
I want to get all the UserExercises of a given user and then display them in my template grouped by category, so if I have: {Ex1: {category: ["C1", "C2"]}, Ex2: {category: "C2"}}
, I want them reordered like this: {"C1": ["Ex1"], "C2": ["Ex2", "Ex1"]}
答案1
得分: 0
以下是您要求的翻译部分:
我建议手动进行后处理,因此:
<pre><code>from itertools import groupby
from operator import attrgetter
qs = (
UserExercises.objects.filter(user=request.user)
.annotate(category_id=F('exercise__category__pk'))
.order_by('category_id')
)
result = {k: list(vs) for k, vs in <b>groupby(</b>qs, <b>attrgetter('category_id'))</b>}</code></pre>
这将把`ExerciseCategory`的主键映射到`UserExercises`列表上,您可以进一步通过获取类别来进行后处理:
<pre><code>categories = {ec.pk: ec for ec in ExerciseCategory.objects.filter(pk__in=result)}
result = {<b>categories[k]</b>: v for k, v in result.items()}</code></pre>
---
> **注意**: 通常,Django模型应该使用*单数*名称,所以应该是`UserExercise`而不是<s>`UserExercises`</s>。
---
> **注意**: 通常最好使用[**`settings.AUTH_USER_MODEL`**&nbsp;<sup>\[Django-doc\]</sup>](https://docs.djangoproject.comen/stable/ref/settings/#std:setting-AUTH_USER_MODEL)来引用用户模型,而不是直接使用[**`User`**模型&nbsp;<sup>\[Django-doc\]</sup>](https://docs.djangoproject.comen/stable/ref/contrib/auth/#django.contrib.auth.models.User)。有关更多信息,请参阅文档中的[*引用`User`模型*部分](https://docs.djangoproject.com/en/stable/topics/auth/customizing/#referencing-the-user-model)。
英文:
I suggest to just post-process this manually, so:
<pre><code>from itertools import groupby
from operator import attrgetter
qs = (
UserExercises.objects.filter(user=request.user)
.annotate(category_id=F('exercise__category__pk'))
.order_by('category_id')
)
result = {k: list(vs) for k, vs in <b>groupby(</b>qs, <b>attrgetter('category_id'))</b>}</code></pre>
this will map the primary key of the ExerciseCategory
on to the list of UserExercises
s, you can further post-process it by fetching the categories as well:
<pre><code>categories = {ec.pk: ec for ec in ExerciseCategory.objects.filter(pk__in=result)}
result = {<b>categories[k]</b>: v for k, v in result.items()}</code></pre>
> Note: normally a Django model is given a singular name, so UserExercise
instead of <s>UserExercises
</s>.
> Note: It is normally better to make use of the settings.AUTH_USER_MODEL
<sup>[Django-doc]</sup> to refer to the user model, than to use the User
model <sup>[Django-doc]</sup> directly. For more information you can see the referencing the User
model section of the documentation.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论