我有一个审核模型:
class ItemModeration(models.Model):
class Meta:
indexes = [
models.Index(fields=['object_id', 'content_type']),
]
unique_together = ('content_type', 'object_id')
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
item = GenericForeignKey('content_type', 'object_id')
published = models.BooleanField(default=False)
...
动态附加审核对象的描述符:
class ItemModerationDescriptor(object):
def __init__(self, **default_kwargs):
self.default_kwargs = default_kwargs
def __get__(self, instance, owner):
ctype = ContentType.objects.get_for_model(instance.__class__)
try:
moderation = ItemModeration.objects.get(content_type__pk=ctype.id,
object_id=instance.pk)
except ItemModeration.DoesNotExist:
moderation = ItemModeration(item=instance,**self.default_kwargs)
moderation.save()
return moderation
还有我要审核的模型:
class Product(models.Model):
user = models.ForeignKey(
User,
null=True,
on_delete=models.SET_NULL)
created = models.DateTimeField(
auto_now_add=True,
blank=True, null=True,
)
modified = models.DateTimeField(
auto_now=True,
blank=True, null=True,
)
name = models.CharField(
max_length=PRODUCT_NAME_MAX_LENGTH,
blank=True, null=True,
)
moderation = ItemModerationDescriptor()
现在我可以轻松看到产品的“发布”状态:
p=Product(name='my super product')
p.save()
print(p.moderation.published)
-> False
通用关系很有用,因为无论类型是什么,我都将能够搜索对象以进行调节:它可能是产品,图像,注释。
to_moderate_qs = ItemModeration.objects.filter(published=False)
现在,如何获得已发布产品的过滤列表? 我想做这样的事情
published_products_qs = Product.objects.filter(moderation__published=True, name__icontains='sony')
但是,当然,它不会起作用,因为moderation
属性不是Django模型字段。
我如何有效地做到这一点?我正在考虑适当的JOIN,但是我不知道如何在不使用原始SQL的情况下使用django做到这一点。
答案 0 :(得分:1)
Django为此提供了一个很好的内置答案:GenericRelation。只需在Product
模型上定义通用关系,然后将其用作常规相关字段即可,而不是描述符:
from django.contrib.contenttypes.fields import GenericRelation
class Product(models.Model):
...
moderation = GenericRelation(ItemModeration)
然后像通常使用相关模型一样处理创建,并且过滤应完全按照您的规定进行。要用作当前系统,在创建新的save
时必须插入一个钩子或ItemModeration
方法来创建相关的Product
对象,但这与其他相关对象没有什么不同django模型。如果您确实想保留描述符类,显然可以为GenericRelation
使用辅助模型字段。
您还可以添加related_query_name
以仅根据ItemModeration
内容类型来过滤Product
对象。
警告,如果您这样做使用GenericRelation
,请注意它具有固定的级联删除行为。因此,如果您不希望在删除ItemModeration
时删除Product
对象,请小心添加pre_delete钩子或等效钩子!
我无意中忽略了问题的OneToOne
方面,因为GenericForeignKey
是一对多关系,但是可以通过巧妙使用QuerySet来实现类似的功能。的确,您不能将product.moderation
作为单个对象进行访问。但是,例如,以下查询在过滤的产品列表上进行迭代,并提取其名称,用户名和相关ModerationItem
的发布日期:
Product.objects.filter(...).values_list(
'name', 'user__username', 'moderation__published'
)
答案 1 :(得分:0)
您必须使用String s = "hi how are you doing today jane";
ArrayList<String> al = new ArrayList<>();
String[] splitted = s.split("\\s+");
int n = splitted.length;
for(int i=0; i<n; i++) {
al.add(splitted[i]);
}
for(int i=0; i<n-1; i=i+2) {
System.out.print(al.get(i+1)+" "+al.get(i)+" ");
}
if((n%2) != 0) {
System.out.print(al.get(n - 1));
}
来按特定模型类型查询表。
像这样:
content_type
有关该主题的更多详细信息,请检查contenttypes doc