【问题标题】:How to cross reference based on foreign keys? Django如何基于外键进行交叉引用?姜戈
【发布时间】:2017-10-16 06:04:25
【问题描述】:

我有一个 Django 应用程序,旅行者“请求”当地人带他出去旅行。出去后,给对方留下参考,提一下是否玩得开心,还有一些文字说明。

我想在主页上自动显示旅行者和当地人已经见面并互相留下参考的最后两个请求。

目前数据来自人口脚本。

这是请求模型:

 class Request(models.Model):
    """traveler requests local to take her out upon liking her profile"""
    traveler = models.ForeignKey(User, related_name='traveler_requests')
    local = models.ForeignKey(User, related_name='local_requested')
    message = models.CharField(max_length=500)
    date = models.DateField()#date of excursion
    local_approval = models.BooleanField(blank=True)

这是参考模型:

class Reference(models.Model):
    author = models.ForeignKey(User, related_name='referencer')#can be local or traveler
    referenced = models.ForeignKey(User, related_name='referencee')#can be local or traveler
    description = models.CharField(max_length=500, default="default reference")
    fun = models.BooleanField() #did you have fun with the person or not?
    date = models.DateField(default=datetime.datetime.now())#in order to pull the last ref on index page
    local = models.BooleanField(default=True) #Is the author a local ?

这是我实现我想要的东西的尝试:

reqs = Request.objects.filter(local_approval=True).order_by('-date')[:2]

for i in range(len(reqs)):
    local_references_traveler = Reference.objects.filter(fun=True, author=reqs[i].local, referenced=reqs[i].traveler, local=True).latest()
    traveler_references_local = Reference.objects.filter(fun=True, author=reqs[i].traveler, referenced=reqs[i].local, local=False).latest()

但是,这通常会带回最后两个请求(按日期),我想返回最后两个请求,其中两个人都为彼此留下了参考并提取这些参考。

这似乎可行的唯一方法是,如果我在填充脚本中填充大量引用,使应用看起来很糟糕。

谢谢!

【问题讨论】:

    标签: python django django-models filter django-views


    【解决方案1】:

    你必须重构你的模型,最好的方法是让“Reference”与“Request”的one_to_one关系,像这样:

    class Reference(models.Model):
        request = models.OneToOneField(
            Request,
            on_delete=models.CASCADE,
            primary_key=True,
        )
        author_desc = models.CharField(max_length=500)
        referenced_desc = models.CharField(max_length=500)
        author_fun = models.BooleanField()
        referenced_fun = models.BooleanField()
        author_date = models.DateField(default=datetime.datetime.now())
        referenced_date = models.DateField(default=datetime.datetime.now())
    

    那你可以试试这个:

    r = Reference.objects.select_related('request').filter(author_fun=True,referenced_fun=True).order_by('-request__date')
    # Don´t forget index or another filter for optimization
    

    或者你可以做一个简单的 FK 来请求,像这样:

    class Reference(model.Models):
        request= ForeignKey(Request)
        author = models.ForeignKey(User, related_name='referencer')#can be local or traveler
        # referenced = models.ForeignKey(User, related_name='referencee')#this isn't necesary
        description = models.CharField(max_length=500, default="default reference")
        fun = models.BooleanField() #did you have fun with the person or not?
        date = models.DateField(default=datetime.datetime.now())#in order to pull the last ref on index page
        local = models.BooleanField(default=True) #Is the author a local ?        
    

    然后你可以做一个注释子句:

    ref_group = Reference.objects.values('request__id') \
        .annotate(num_reference=Count('id')) \
        .filter(num_reference=2)
        .order_by('-request__id')
    

    ...有了这个,你可以得到所有的“request.id”和两个引用。

    【讨论】:

      猜你喜欢
      • 2016-04-25
      • 2019-01-04
      • 2010-12-21
      • 1970-01-01
      • 2021-12-03
      • 2020-08-17
      • 2012-05-29
      • 1970-01-01
      • 2015-09-30
      相关资源
      最近更新 更多