根据其发布日期,在同一页面显示来自不同型号的对象 [英] Display objects from different models at the same page according to their published date

查看:90
本文介绍了根据其发布日期,在同一页面显示来自不同型号的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序有三种不同的型号。都按照我的预期工作。

  class Tender(models.Model):
title = models.CharField(max_length = 256)
description = models.TextField()
department = models.CharField(max_length = 50)
address = models.CharField(max_length = 50)
nature_of_work = models.CharField(choices = WORK_NATURE,max_length = 1)
period_of_completion = models.DateField()
pubdat = models.DateTimeField(default = timezone.now)

class Job(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
title = models.CharField(max_length = 256)
qualification = models.CharField(max_length = 256)
interview_type = models.CharField(max_length = 2,choices = INTERVIEW_TYPE)
type_of_job = models.CharField(max_length = 1,choices = JOB_TYPE)
number_of_vacancies = models.IntegerField()
employer = models.CharField(max_length = 50)
salary = models.IntegerField()
pubdat = models.DateTimeField(default = timezone.now)

class新闻(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
title = models.CharField(max_length = 150)
body = models.TextField()
pubdat = models.DateTimeField(default = timezone.now)

现在我在每个模型的单独页面上显示每个模型(例如,在作业页面中,我只显示作业。)。但是现在在主页上,我想根据他们发布的日期在同一页面显示这些。如何在同一页面显示不同型号的不同对象?我做一个单独的模型,如 class Post ,然后使用信号创建一个新的帖子,每当从 Tender Job 新闻?我真的希望有一个更好的方式来实现这一点。还是使用多表继承?请帮帮我。谢谢。



更新:



我不想显示每个的模型对象分别在同一页。但是像Facebook或任何其他社交媒体的饲料。假设在fb中,任何帖子(无论是图像,状态,共享)都在主页内一起显示。同样在我的情况下,假设创建了一个新的Job对象,之后创建一个新的News对象。然后,我想先显示新闻对象,然后显示Job对象,等等。

解决方案

/ h2>

另外两个解决方案有两个解决方案。这两个涉及三个查询。而您正在使用 .all()查询整个表。这些查询的结果组合成一个列表。如果您的每个表都有大约10k的记录,这将对您的wsgi服务器和数据库造成巨大压力。即使每个表只有100个记录,您在视图中不必要循环300次。



一个有效的工作解决方案。



多表继承如果你想要一个高效的解决方案,绝对是正确的方法。您的模型可能如下所示:

  class Post(models.Model):
title = models.CharField(max_length = 256)
description = models.TextField()
pubdat = models.DateTimeField(default = timezone.now,db_index = True)

class Tender(Post):
department = models.CharField(max_length = 50)
address = models.CharField(max_length = 50)
nature_of_work = models.CharField(choices = WORK_NATURE,max_length = 1)
period_of_completion = $($)

class Job(Post)
user = models.ForeignKey(settings.AUTH_USER_MODEL)
qualification = models.CharField(max_length = 256)
interview_type = models.CharField(max_length = 2,choices = INTERVIEW_TYPE)
type_of_job = models.CharField(max_length = 1,choices = JOB_TYPE)
number_of_vacancies = models.IntegerField()
雇主= models.CharField(max_length = 50)
salary = models.IntegerField()


class New s(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)

def _get_body(self):
return self.description

body = property(_get_body)

现在你的查询只是

  Post.objects.select_related(
'job','tender','news')。all()。order_by(' - pubdat')#你真的应该切

pubdat 字段是现在索引(参考我发布的新的Post模型)。这使查询真的很快。 python中的所有记录都没有迭代。



如何找出模板中哪一个?有这样的东西。

  {%if post.tender%} 

{%else%}
{%if post.news%}
{%else%}
{%else%}



进一步优化



您的设计中有一些空间规范化数据库。例如,同一家公司可能会发布多个工作或招标。因为这样的公司模式可能会有用。



一个更有效的解决方案。



多表继承或多数据库查询?您甚至可以消除渲染每个单独项目的开销的解决方案?



这是由重新排序的集合。每次保存 Post Job 新闻对象将其添加到重新排序的集合中。从django.db.models.signals导入pre_delete,post_save
从django.forms.models导入model_to_dict $ b

 
$ b @receiver(post_save,sender = News)
@receiver(post_save,sender = Post)
@receiver(post_save,sender = Job)

def add_to_redis(发件人,实例,** kwargs):
rdb = redis.Redis()

#instead添加实例,可以考虑添加
#rendered HTML,那么应该节省更多的CPU周期。

rdb.zadd(key,instance.pubdat,model_to_dict(instance)

if(rdb.zcard> 100):#选择合适的数字
rdb .zremrangebyrank(key,0,100)

同样,你需要添加一个pre_delete来将它们从redis



这种方法的明显优势是,您根本不需要任何数据库查询,您的模型仍然很简单,您可以在混合中捕获如果你在twitter上,你的时间表可能是通过类似这样的机制产生的。


I have three different models for my app. All are working as I expected.

class Tender(models.Model):
    title = models.CharField(max_length=256)
    description = models.TextField()
    department = models.CharField(max_length=50)
    address = models.CharField(max_length=50)
    nature_of_work = models.CharField(choices=WORK_NATURE, max_length=1)
    period_of_completion = models.DateField()
    pubdat = models.DateTimeField(default=timezone.now)    

class Job(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    title = models.CharField(max_length=256)
    qualification = models.CharField(max_length=256)
    interview_type = models.CharField(max_length=2, choices=INTERVIEW_TYPE)
    type_of_job = models.CharField(max_length=1, choices=JOB_TYPE)
    number_of_vacancies = models.IntegerField()
    employer = models.CharField(max_length=50)
    salary = models.IntegerField()    
    pubdat = models.DateTimeField(default=timezone.now)

class News(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    title = models.CharField(max_length=150)
    body = models.TextField()
    pubdat = models.DateTimeField(default=timezone.now)

Now I am displaying each of them at separate page for each of the model (e.g. in the jobs page, I am displaying only the jobs.). But now at the home page, I want to display these according to their published date at the same page. How can I display different objects from different models at the same page? Do I make a separate model e.g. class Post and then use signal to create a new post whenever a new object is created from Tender, or Job, or News? I really hope there is a better way to achieve this. Or do I use multi-table inheritance? Please help me. Thank you.

Update:

I don't want to show each of the model objects separately at the same page. But like feeds of facebook or any other social media. Suppose in fb, any post (be it an image, status, share) are all displayed together within the home page. Likewise in my case, suppose a new Job object was created, and after that a new News object is created. Then, I want to show the News object first, and then the Job object, and so on.

解决方案

A working solution

There are two working solutions two other answers. Both those involve three queries. And you are querying the entire table with .all(). The results of these queries combined together into a single list. If each of your tables has about 10k records, this is going to put enormous strain on both your wsgi server and your database. Even if each table has only 100 records each, you are needlessly looping 300 times in your view. In short slow response.

An efficient working solution.

Multi table inheritance is definitely the right way to go if you want a solution that is efficient. Your models might look like this:

class Post(models.Model):
    title = models.CharField(max_length=256)
    description = models.TextField()
    pubdat = models.DateTimeField(default=timezone.now, db_index = True)    

class Tender(Post):
    department = models.CharField(max_length=50)
    address = models.CharField(max_length=50)
    nature_of_work = models.CharField(choices=WORK_NATURE, max_length=1)
    period_of_completion = models.DateField()

class Job(Post):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    qualification = models.CharField(max_length=256)
    interview_type = models.CharField(max_length=2, choices=INTERVIEW_TYPE)
    type_of_job = models.CharField(max_length=1, choices=JOB_TYPE)
    number_of_vacancies = models.IntegerField()
    employer = models.CharField(max_length=50)
    salary = models.IntegerField()    


class News(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)

    def _get_body(self):
        return self.description

    body = property(_get_body)

now your query is simply

 Post.objects.select_related(
   'job','tender','news').all().order_by('-pubdat')   # you really should slice

The pubdat field is now indexed (refer the new Post model I posted). That makes the query really fast. There is no iteration through all the records in python.

How do you find out which is which in the template? With something like this.

{% if post.tender %}

{% else %} 
   {% if post.news %}
   {% else %}
{% else %}

Further Optimization

There is some room in your design to normalize the database. For example it's likely that the same company may post multiple jobs or tenders. As such a company model might come in usefull.

An even more efficient solution.

How about one without multi table inheritance or multiple database queries? How about a solution where you could even eliminate the overhead of rendering each individual item?

That comes with the courtesy of redis sorted sets. Each time you save a Post, Job or News, object you add it to a redis sorted set.

from django.db.models.signals import pre_delete, post_save
from django.forms.models import model_to_dict

@receiver(post_save, sender=News)
@receiver(post_save, sender=Post)
@receiver(post_save, sender=Job)

def add_to_redis(sender, instance, **kwargs):
    rdb = redis.Redis()

    #instead of adding the instance, you can consider adding the 
    #rendered HTML, that ought to save you a few more CPU cycles.

    rdb.zadd(key, instance.pubdat, model_to_dict(instance)

    if (rdb.zcard > 100) : # choose a suitable number
         rdb.zremrangebyrank(key, 0, 100)

Similarly, you need to add a pre_delete to remove them from redis

The clear advantage of this method is that you don't need any database queries at all and your models continue to be really simple + you get catching thrown in the mix. If you are on twitter your timeline is probably generated through a mechanism similar to this.

这篇关于根据其发布日期,在同一页面显示来自不同型号的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆