首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >具有不同模型查询集的InlineFormSet

具有不同模型查询集的InlineFormSet
EN

Stack Overflow用户
提问于 2009-08-12 22:19:31
回答 2查看 540关注 0票数 1

我们要做的是使用不同模型的一些查询集,用初始值填充一个内联表单列表。我们有产品、指标(一些类别、类型或评级)和一个评级,它存储实际的评级并将指标与产品联系起来。

代码语言:javascript
运行
复制
class Product(models.Model):
    name = models.CharField(max_length=100)
    price = models.IntegerField(max_length=6)

class Metric(models.Model):
    name = models.CharField(max_length=80)
    description = models.TextField()


class Rating(models.Model)
    rating = models.IntegerField(max_length=3)

    metric = models.ForeignKey(Metric)
    product = models.ForeignKey(Product)

我们要得到的最终结果是产品管理页面上产品的所有可能评级的列表。如果我们的数据库中有20个指标,当我们转到产品页面时,我们希望在页面上看到20个评级表单,每个表单都绑定到一个不同的指标。我们不能使用基于评分的查询集来填充页面,因为特定产品/指标组合的评分可能还不存在。

我们一直在研究Django中的所有表单和表单集代码,并希望能提出一个如此简单的解决方案:

http://www.thenestedfloat.com/articles/limiting-inline-admin-objects-in-django

他只是重写了BaseInlineFormSet中的一些东西,并将其提供给内联。也许我们可以做这样的东西

代码语言:javascript
运行
复制
class RatingInlineFormset(BaseInlineFormset):

有一些重写。有什么想法吗?

EN

回答 2

Stack Overflow用户

发布于 2009-12-04 06:42:49

您正在寻找管理员解决方案还是前端解决方案?管理方式如下所示,您可以对其进行反向工程以获得类似的前端解决方案:

代码语言:javascript
运行
复制
# admin.py

class RatingInline(admin.StackedInline):
    model = Rating

class ProductAdmin(admin.ModelAdmin):
    inlines = [ 
        RatingInline
    ]

class MetricAdmin(admin.ModelAdmin):
    pass

class RatingAdmin(admin.ModelAdmin):
    pass

admin.site.register(Product, ProductAdmin)
admin.site.register(Metric, MetricAdmin)
admin.site.register(Rating, RatingAdmin)
票数 0
EN

Stack Overflow用户

发布于 2012-01-24 18:32:13

我已经设法实现了类似的功能,有点像这样:

代码语言:javascript
运行
复制
from django.forms.models import BaseInlineFormSet
from django.forms.models import inlineformset_factory    

class RawQueryAdapter(object):
    """
    Implement some extra methods to make a RawQuery
    compatible with FormSet, which is expecting a QuerySet
    """
    ordered = True

    def __init__(self, qs):
        self.qs = qs
        self.db = qs.db

    def filter(self, *args, **kwargs):
        return self

    def __len__(self):
        return len(list(self.qs))

    def __getitem__(self, key):
        return self.qs[key]

class BaseRatingFormSet(BaseInlineFormSet):
    def __init__(self, *args, **kwargs):
        sql = """
            SELECT r.id, %s as product_id, m.id as metric_id
            FROM myapp_metric m
            LEFT JOIN myapp_rating r ON m.id = r.metric_id
            AND r.product_id = %s
        """
        id = kwargs['instance'].id or 'NULL'
        qs = RawQueryAdapter(Rating.objects.raw(sql % (id, id)))
        super(BaseRatingFormSet, self).__init__(queryset=qs, *args, **kwargs)

    def _construct_form(self, i, **kwargs):
        pk_key = "%s-%s" % (self.add_prefix(i), self.model._meta.pk.name)
        if self.data.get(pk_key) == '':
            # Skip parent (BaseModelFormSet) implementation as it won't work
            # with our injected raw data
            if i < self.initial_form_count() and not kwargs.get('instance'):
                kwargs['instance'] = self.get_queryset()[i]
            return super(BaseModelFormSet, self)._construct_form(i, **kwargs)
        return super(BaseRatingFormSet, self)._construct_form(i, **kwargs)

RatingFormSet = inlineformset_factory(
    Product, Rating,
    can_delete=False,
    max_num=0,
    formset=BaseRatingFormSet,
)

编辑:条件必须在LEFT JOIN中完成,而不是WHERE中,否则会缺少行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1269052

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档