【问题标题】:Displaying data returned from a model Manager in django在 django 中显示从模型管理器返回的数据
【发布时间】:2016-05-03 19:57:49
【问题描述】:

我将 MySQL 与 Django 一起使用,但无法查看在模型管理器中执行的查询返回的数据。

页面与表格一起呈现,边框和分页正在工作,但是表格中没有出现任何字段值。

我猜在返回查询结果和以 html 形式呈现之间需要一个步骤,但我很难过。

对于上下文,我正在设置我的经理,以便我可以执行比 Django 提供的更复杂的查询。

我遵循了一些使用模型管理器的示例,并以一个相当简单的查询作为开始 - .. 我在本网站之外研究过的众多参考资料之一:https://docs.djangoproject.com/en/dev/topics/db/managers/#custom-managers

在花了很多时间搜索之后,我相信这里有人可以提供帮助。提前致谢!!

这里是模型管理器:

class ElectionsManager(models.Manager):
def is_active(self):
    from django.db import connection
    cursor = connection.cursor()
    cursor.execute("""
                    SELECT * 
                    FROM
                        newvoterproject.fullvh vh1
                    WHERE
                    vh1.city = 'Glocester' and 
                    vh1.current_party = 'd' 
                    group by 
                        vh1.city,
                        vh1.street_name,
                        vh1.street_name_2,
                        vh1.street_number, 
                        vh1.unit
                    ;""")
    result_list = cursor.fetchall()
    return result_list

这里是模型的一个片段:

class Election(models.Model):
voter_id = models.CharField(primary_key=True, max_length=25)
last_name = models.CharField(max_length=50, blank=True, null=True)
first_name = models.CharField(max_length=50, blank=True, null=True)
middle_name = models.CharField(max_length=50, blank=True, null=True)
current_party = models.CharField(max_length=50, blank=True, null=True)
street_number = models.CharField(max_length=50, blank=True, null=True)
street_name = models.CharField(max_length=50, blank=True, null=True)
street_name_2 = models.CharField(max_length=50, blank=True, null=True)
unit = models.CharField(max_length=50, blank=True, null=True)
city = models.CharField(max_length=50, blank=True, null=True)
state = models.CharField(max_length=50, blank=True, null=True)
zip_code = models.CharField(max_length=50, blank=True, null=True)
zip_code_4 = models.CharField(max_length=50, blank=True, null=True)
precinct = models.CharField(max_length=50, blank=True, null=True)
status = models.CharField(max_length=50, blank=True, null=True)
objects = ElectionsManager() # model manager 

class Meta:
    managed = False
    verbose_name = 'Election'
    verbose_name_plural = 'Elections'
    db_table = 'fullvh'

def __str__(self):
    return '%s %s' % (self.first_name, self.last_name)

从视图调用模型管理器:

def vhistfun(request):
election_table = Election.objects.is_active()
paginator = Paginator(election_table , 25) # Show 25 contacts per page - may want to change this to READ 25 at a time...
page = request.GET.get('page')
try:
    electpage = paginator.page(page)
except PageNotAnInteger:   
    electpage = paginator.page(1)
except EmptyPage:      
    electpage = paginator.page(paginator.num_pages)

context = {'electpage': electpage,
           }
return render(request, 'elections/electable.html', context)

.. 以及处理结果的 html 片段

    {% for elect in electpage  %}
    <tr id="voterrowclass" class=""> 
        <td> {{ elect.first_name|lower|capfirst }} </td>
        <td> {{ elect.last_name|lower|capfirst }} </td>
        <td> {{ elect.current_party}} </td>
        <td> {{ elect.street_number}} {{ elect.unit}} </td>
        <td> {{ elect.street_name|lower|capfirst}} {{ elect.street_name_2|lower|capfirst}} </td>
        <td> {{ elect.city|lower|capfirst}} </td>
    </tr> <!-- # model data sent from view -->
{% endfor %}

【问题讨论】:

    标签: mysql django django-models


    【解决方案1】:

    您的自定义管理器方法未返回 Election 对象;它返回表示数据库行的元组。因此,您不能通过字段名称引用模板中的结果,就好像它们是对象一样。

    这真的不是经理的职责;您的管理器方法应始终返回查询集。

    【讨论】:

    • 那么有没有办法将结果转换为一组可迭代对象? django 中的查询集功能无法满足我的需求。
    • 它们是可迭代的;问题不在于 for 循环,而是您按名称引用每个字段的事实,而您只有一个值元组。但是,您可能应该使用 raw 查询集方法而不是直接调用游标,因为它确实映射到字段名称。
    【解决方案2】:

    感谢您的见解。

    我进行了一些更改并使其正常工作,但没有使用模型管理器(目前)。

    • 我现在在 models.py 中删除了对我的模型管理器的引用 - (我可能会在以后的迭代/重构时将其添加回来)
    • 使用对我的数据库的原始 sql 调用,我成功地处理了一个相当简单的查询的结果(正确的数据填充在我的 html 中 - 不需要更改 html)

    下面是增强的视图,可以让一切正常工作:

    def vhistfun(request):
    election_table = Election.objects.raw("""
                    SELECT *
                FROM
                    newvoterproject.fullvh vh1
                WHERE
                    vh1.city = 'Glocester'
                        AND (vh1.current_party = 'r' or vh1.current_party = 'u') 
                        GROUP BY vh1.city , 
                        vh1.street_name ,  
                        CONVERT(SUBSTRING_INDEX(vh1.street_number,'-',-1),UNSIGNED INTEGER)  , 
                        vh1.unit
                ;
                        """)
    party_list=('r','u')
    town_list=('Glocester')
    query_information ='Voters in the 2012 Presidential Election (election_3) and either the 2008 Presidential Election (election_8)or the 2012 Presidential Primary (election_5)'
    
    paginator = Paginator(list(election_table), 10) # NOTE > this was changed from paginator = Paginator(election_table , 25)
    page = request.GET.get('page')
    try:
        electpage = paginator.page(page)
    except PageNotAnInteger:      
        electpage = paginator.page(1)
    except EmptyPage:     
        electpage = paginator.page(paginator.num_pages)
    
    context = {'electpage': electpage,
               'party_list': party_list,
               'town_list': town_list,
               'query_information ': query_information
               }
    return render(request, 'elections/electable.html', context)
    

    请注意/注意 - 使用 objects.raw 会导致分页出现此问题:

    object of type 'int' has no len()
    

    我在这里找到了解决方法:Django paginator and raw SQL

    现在我正在用数据填充我的表,并将继续进行我的项目需要的更高级的查询....

    我暂时不回答这个问题。 虽然我成功地使用 raw 获取了我需要的数据,但它并没有解决所提出的问题 - 为什么模型管理器中的查询没有在 html 上正确显示数据......

    【讨论】:

      猜你喜欢
      • 2019-12-17
      • 2016-09-16
      • 2021-09-14
      • 2014-09-08
      • 1970-01-01
      • 1970-01-01
      • 2018-06-25
      • 2016-11-19
      • 1970-01-01
      相关资源
      最近更新 更多