Django中的查询(备忘)

  1. Html代码:
Html代码:
  1. <div class="pageHeader">
  2. <form οnsubmit="return navTabSearch(this);" action="{% url accounts_search %}" method="post">
  3. <div class="searchBar">
  4. <ul class="searchContent">
  5. <li>
  6. <label>名称:</label>
  7. <input type="text" name="q" />
  8. </li>
  9. </ul>
  10. <div class="subBar">
  11. <ul>
  12. <li><div class="buttonActive"><divclass="buttonContent"><button type="submit">查询</button></div></div></li>
  13. </ul>
  14. </div>
  15. </div>
  16. </form>
  17. </div>
<div class="pageHeader">
		<form οnsubmit="return navTabSearch(this);" action="{% url accounts_search %}" method="post">
		<div class="searchBar">
			<ul class="searchContent">
				<li>
					<label>名称:</label>
					<input type="text" name="q" />
				</li>
			</ul>
			<div class="subBar">
				<ul>
					<li><div class="buttonActive"><div class="buttonContent"><button type="submit">查询</button></div></div></li>
				</ul>
			</div>
		</div>
		</form>
	</div>


url映射:

  1. url(r'^search/$','account.views.search',name="accounts_search"),
url(r'^search/$', 'account.views.search',name="accounts_search"),


python代码:

  1. def search(request):
  2. if 'q'in request.POSTand request.POST['q']:
  3. q = request.POST['q']
  4. users = User.objects.filter(username__icontains = q)
  5. #return render_to_response('account/welcome.html', {'users':users},{'q':q})
  6. else:
  7. #return render_to_response('account/welcome.html')
  8. users = User.objects.order_by('-id')

  9. #users = User.objects.order_by('-id')
  10. paginator = Paginator(users, 10)
  11. page = request.POST.get('pageNum',1)
  12. try:
  13. users = paginator.page(page)
  14. except (EmptyPage, InvalidPage):
  15. users = paginator.page(paginator.num_pages)
  16. if 'q'in request.POSTand request.POST['q']:
  17. return render_to_response('account/welcome.html', {'users':users,'currentPage':page,'numPerPage':5,'q':q})
  18. else:
  19. return render_to_response('account/welcome.html', {'users':users,'currentPage':page,'numPerPage':5})
def search(request):
    if 'q' in request.POST and request.POST['q']:
        q = request.POST['q']
        users = User.objects.filter(username__icontains = q)
        #return render_to_response('account/welcome.html', {'users':users},{'q':q})
    else:
        #return render_to_response('account/welcome.html')
        users = User.objects.order_by('-id')
    
    #users = User.objects.order_by('-id')
    paginator = Paginator(users, 10)
    page = request.POST.get('pageNum',1)
    try:
        users = paginator.page(page)
    except (EmptyPage, InvalidPage):
        users = paginator.page(paginator.num_pages)
    if 'q' in request.POST and request.POST['q']:
        return render_to_response('account/welcome.html', {'users':users, 'currentPage':page, 'numPerPage':5, 'q':q})
    else:  
        return render_to_response('account/welcome.html', {'users':users, 'currentPage':page, 'numPerPage':5})


django查询数据库

项目原框架中有一个test.objects.filter,我一直以为是像java中的类反射一样的东东,经过请教才知道,这个原来是数据库查询的,于是上网搜了一下,原文地址:http://blog.csdn.net/zhangzhenhu/article/details/6080414

特殊过滤

django数据库查询时,一般就是

modelname.objects.all();

modelname.objects.filter();

modelname.objects.get()等等,在过滤时,如果过滤条件假设是其中的某一字段,比如 id,要求id=5,或者是一个范围比如1 < id < 5,前者可以写成filter(id=5),后者可以写成filter(id between 1 and 5),但是当过滤条件为id属于一集合,这时可以写成filter(id__in = list),list为一个[],id__in为双下划线,关于双下划线的参数还有很多....

学习了,记录哈

刚才又看到一个描述查询的博客,博客源地址如下:http://blog.csdn.net/cai0611/article/details/6560377

这次就当是补充一下了

__exact 精确等于 like 'aaa'
__iexact 精确等于 忽略大小写 ilike 'aaa'
__contains 包含 like '%aaa%'
__icontains 包含 忽略大小写 ilike '%aaa%',但是对于sqlite来说,contains的作用效果等同于icontains。
__gt 大于
__gte 大于等于
__lt 小于
__lte 小于等于
__in 存在于一个list范围内
__startswith 以...开头
__istartswith 以...开头 忽略大小写
__endswith 以...结尾
__iendswith 以...结尾,忽略大小写
__range 在...范围内
__year 日期字段的年份
__month 日期字段的月份
__day 日期字段的日
__isnull=True/False
__isnull=True 与 __exact=None的区别

专门介绍那些双下划线的东西,作为了解。估计能够用得到

Django的like查询中%与_的转码操作

我们知道在SQL查询中如果使用like进行模糊查找,需要使用“%”和“_”这两个符号。”%”表示匹配任意字符,”_”表示匹配一个字符。Django已经封装了like的查询放,比如:iexact, contains, icontains, startswith, istartswith, endswith 以及 iendswith。 那么如果我们相应查询的字段值中包含了上述的两个特殊负号,Django会怎么处理呢?

答案是,Django会自动将这两个符号转义。比如下面的例子:

>>> Entry. objects. filter (headline__contains =’%’ )

Django转义后的SQL语句类似下面这样:

SELECT ... WHERE headline LIKE ’%\%%’;

搜索
在web应用上,有两个关于搜索获得巨大成功的故事:Google和Yahoo,通过搜索,他们建立了几十亿美元的业务,几乎每个网站都有很大的比例访问量来自这两个搜索引擎。甚至,一个网站是否成功取决于其站内搜索的质量,因此,在我们这个网站添加搜索功能看起来好一些。
开始在URLconf (mysite.urls )添加搜索视图。添加类似
(r'^search/$','mysite.books.views.search')
下一步,在视图模块(mysite.books.views )中写这个 search视图方法:
from django.db.models import Q
from django.shortcuts import render_to_response
from models import Book
def search(request):
query = request.GET.get('q', '')
if query:
qset = (
Q(title__icontains=query) |
Q(authors__first_name__icontains=query) |
Q(authors__last_name__icontains=query)
)
results = Book.objects.filter(qset).distinct()
else:
results = []
return render_to_response("books/search.html", {"results": results,"query": query})
这里有一些需要注意的,首先request.GET,这从Django中怎样访问GET数据;POST数据通过类似的request.POST对象访问。这些对象行为与标准Python字典很像,在附录H中列出来其另外的特性。

什么是 GET and POST 数据?
GET和POST是浏览器使用的两个方法,用于发送数据到服务器端,一般来说,会在html表单里面看到:
<form action="/books/search/" method="get">
它指示浏览器向/books/search/以GET的方法提交数据,关于GET和POST这两个方法之间有很大的不同,不过我们暂时不深入它,如果你想了解更多,可以访问:http://www.w3.org/2001/tag/doc/whenToUseGet.html
所以下面这行:
query = request.GET.get('q', '')
寻找名为q的GET参数,而且如果参数没有提交,返回一个空的字符串。
注意:在request.GET中使用了get()方法,这可能让大家不好理解,这里的get()是每个python的字典数据类型都有的方法。使用的时候要小心:假设request.GET包含一个'q'的key是不安全的,所以我们使用 get('q', '')提供一个缺省的返回值''(一个空字符串)。
如果只是使用 request.GET['q']访问变量,在Get数据时q不可得,可能引发 KeyError。
其次,关于Q,Q对象在这个例子里用于建立复杂的查询,搜索匹配查询的任何书籍,技术上Q对象包含QuerySet,可以在附录C中进一步阅读。
在这个查询中,icontains使用SQL的LIKE操作符,是大小写不敏感的。
既然搜索依靠多对多域来实现,就有可能对同一本书返回多次查询结果(例如:一本书有两
个作者都符合查询条件)。因此添加.distinct()过滤查询结果,消除重复部分。
现在仍然没有这个搜索视图的模板,可以如下实现:
< !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
< html lang="en">
< head>
< title>Search{% if query %} Results{% endif %}</title>
< /head>
< body>
< h1>Search</h1>
< form action="." method="GET">
< label for="q">Search: </label>
< input type="text" name="q" value="{{ query|escape }}">
< input type="submit" value="Search">
< /form>
{% if query %}
< h2>Results for "{{ query|escape }}":</h2>
{% if results %}
< ul>
{% for book in results %}
< li>{{ book|escape }}</l1>
{% endfor %}
< /ul>
{% else %}
< p>No books found</p>
{% endif %}
{% endif %}
< /body>
< /html>
希望你已经很清楚地明白这个实现,不过,有几个细节需要指出:
表单的action是“.”,表示当前的URL,这是一个标准的最佳惯常处理方式:不使用独立的视图分别来显示表单页面和结果页面,而是使用单个视图页面来处理表单并显示搜索结果。
我们把返回的查询值重新插入到<input>中去,以便于读者可以完善他们的搜索内容,而不必重新输入搜索内容。
在所有使用query和book的地方,我们通过escape过滤器来确保任何可能的恶意的搜索文字被过滤出去,以保证不被插入到页面里。这对处理任何用户提交数据来说是必须的!否则的话你就开放你的网站允许跨站点脚本(XSS)攻击。在第十九章中将详细讨论了XSS和安全。不过,我们不必担心数据库对可能有危害内容的查询的处理。 Django的数据库层在这方面已经做过安全处理。【译注:数据库层对查询数据自动Escape,所以不用担心】
现在我们已经作了搜索,进一步要把搜索表单加到所有的页面(例如,在base模板),这个可以由你自己完成。

完美表单
表单经常引起站点用户的反感,我们考虑一下一个假设的完美的表单的行为:
它应该问用户一些信息,显然,由于可用性的问题,使用HTML<label>元素和有用的上下文帮助是很重要的。
所提交的数据应该多方面的验证,Web应用安全的金科玉律是从不要相信进来的数据,所以验证是必需的。
如果用户有一些错误,表单应该重新显示详情,错误信息,原来的数据应该已经填好,避免用户重新录入。
表单应该在所有域验证正确前一直重新显示。
建立这样的表单好像需要做很多工作!幸好,Django的表单框架已经设计的可以为你做绝大部分的工作,你只需要提供表单域的描述,验证规则和简单的模板即可,这样就只需要一点的工作就可以做成一个完美的表单。

创建一个回馈表单
做好一个网站需要注意用户反馈,很多站点好像忘记这个,他们把联系信息放在FAQ后面,而且好像很难联系到实际的人。
一个百万用户级的网站,可能有些合理的策略,如果建立一个面向用户的站点,需要鼓励回馈。我们建立一个简单的回馈表单,用来展示Django的表单框架。
开始,在URLconf里添加:
(r'^contact/$', 'mysite.books.views.contact')
然后定义表单,在Django中,表单的创建类似MODEL:使用Python类来声明。这里是我们简单表单的类,为了方便,把它写到新的forms.py文件中,这个文件在app目录下。
from django import newforms as forms
TOPIC_CHOICES = (
('general', 'General enquiry'),
('bug', 'Bug report'),
('suggestion', 'Suggestion'),
)
class ContactForm(forms.Form):
topic = forms.ChoiceField(choices=TOPIC_CHOICES)
message = forms.CharField()
sender = forms.EmailField(required=False)
New Forms是什么?
当Django最初推出的时候,有一个复杂而难用的form系统。用它来构建表单简直就是噩梦,所以它在新版本里面被一个叫做newforms的系统取代了。但是鉴于还有很多代码依赖于老的那个form系统,暂时Django还是同时保有两个forms包。在本书写作期间,Django的老form系统还是在 django.forms 中,新的form系统位于django.newforms 中,这种状况迟早会改变, django.forms 会指向新的form包。但是为了让本书中的例子尽可能广泛地工作,所有的代码中仍然会使用 django.newforms。
一个Django表单是django.newforms.Form的子类,就像Django模型是 django.db.models.Model 的子类一样。在django.newforms模块中还包含很多Field类,Django的文档
http://www.djangoproject.com/documentation/0.96/newforms/ )中包含了一个可用的Field列表。
我们的ContactForm包含三个字段:一个topic,它是一个三选一的选择框;一个message,它是一个文本域;一个sender,它是一个可选的email域。还有很多字段类型可供选择,如果它们都不满足要求,你可以考虑自己写一个。
form对象自己知道如何做一些有用的事情。它能校验数据集合,生成HTML“部件”,生成一些有用的错误信息,当然,如果你确实很懒,它也能绘出整个form。现在让我们把它嵌入一个视图,看看怎么样使用它。在views.py里面:
from django.db.models import Q
from django.shortcuts import render_to_response
from models import Book
**from forms import ContactForm**
def search(request):
query = request.GET.get('q', '')
if query:
qset = (
Q(title__icontains=query) |
Q(authors__first_name__icontains=query) |
Q(authors__last_name__icontains=query)
)
results = Book.objects.filter(qset).distinct()
else:
results = []
return render_to_response("books/search.html", {"results": results,"query": query})
**def contact(request):**
**form = ContactForm()**
**return render_to_response('contact.html', {'form': form})**
添加contact.html文件:
< !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
< html lang="en">
< head>
< title>Contact us</title>
< /head>
< body>
< h1>Contact us</h1>
< form action="." method="POST">
< table>
{{ form.as_table }}
< /table>
< p><input type="submit" value="Submit"></p>
< /form>
< /body>
< /html>
最有意思的一行是{{ form.as_table }},form是ContactForm的实例,通过render_to_response方法把它传递给模板。as_table是form的一个方法,它把form渲染成一系列的表格行(as_ul和as_p也是起着相似的作用)。生成的HTML像这样:
<tr>
< th><label for="id_topic">Topic:</label></th>
< td>
< select name="topic" id="id_topic">
< option value="general">General enquiry</option>
< option value="bug">Bug report</option>
< option value="suggestion">Suggestion</option>
< /select>
< /td>
< /tr>
< tr>
< th><label for="id_message">Message:</label></th>
< td><input type="text" name="message" id="id_message" /></td>
< /tr>
< tr>
< th><label for="id_sender">Sender:</label></th>
< td><input type="text" name="sender" id="id_sender" /></td>
< /tr>
请注意:<table>和<form>标签并没有包含在内,需要在模板里定义它们,这给予我们更大的控制权去决定form提交时的行为。Label元素是包含在内的,令访问性更佳(因为label的值会显示在页面上)。
我们的form现在使用了一个<input type=”text”>部件来显示message字段。但我们不想限制我们的用户只能输入一行文本,所以我们用一个<textarea>部件来替代:
class ContactForm(forms.Form):
topic = forms.ChoiceField(choices=TOPIC_CHOICES)
message = forms.CharField(**widget=forms.Textarea()** )
sender = forms.EmailField(required=False)
forms框架把每一个字段的显示逻辑分离到一组部件(widget)中。每一个字段类型都拥有一个默认的部件,我们也可以容易地替换掉默认的部件,或者提供一个自定义的部件。
现在,提交这个form没有在后台做任何事情。让我们把我们的校验规则加进去:
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
else:
form = ContactForm()
return render_to_response('contact.html', {'form': form})
一个form实例可能处在两种状态:绑定或者未绑定。一个绑定的实例是由字典(或者类似于
字典的对象)构造而来的,它同样也知道如何验证和重新显示它的数据。一个未绑定的form
是没有与之联系的数据,仅仅知道如何显示其自身。
现在可以试着提交一下这个空白的form了,将会被重新显示出来,显示一个验证错误,提示我们message字段是必须的。现在输入一个不合法的email地址,EmailField知道如何验证email地址,大多数情况下这种验证是合理的。

设置初始数据
向form的构造器函数直接传递数据会把这些数据绑定到form,指示form进行验证。我们有时也需要在初始化的时候预先填充一些字段——比方说一个编辑form。我们可以传入一些初始的关键字参数:
form = CommentForm(initial={'sender': 'user@example.com'})
如果我们的form总是会使用相同的默认值,我们可以在form自身的定义中设置它们:
message = forms.CharField(widget=forms.Textarea(), **initial="Replace with your feedback"** )

处理提交
当用户填完form,完成了校验,我们需要做一些有用的事情了。在本例中,我们需要构造并发送一个包含了用户反馈的email,我们将会使用Django的email包来完成。
首先,我们需要知道用户数据是不是真的合法,如果是这样,我们就要访问已经验证过的数据。forms框架甚至做的更多,它会把它们转换成对应的Python类型。我们的联系方式form仅仅处理字符串,但是如果我们使用IntegerField或者DataTimeField,forms框架会保证我们
从中取得类型正确的值。
测试一个form是否已经绑定到合法的数据,使用is_valid()方法:
form = ContactForm(request.POST)
if form.is_valid():
# Process form data
现在我们要访问数据了。我们可以从request.POST里面直接把它们取出来,但是这样做我们就丧失了由framework为我们自动做类型转换的好处了。所以我们要使用form.clean_data:
if form.is_valid():
topic = form.clean_data['topic']
message = form.clean_data['message']
sender = form.clean_data.get('sender', 'noreply@example.com')
# ...
请注意因为sender不是必需的,我们为它提供了一个默认值,终于,我们要记录下用户的反馈了,最简单的方法就是把它发送给站点管理员,我们可以使用send_mail方法:
from django.core.mail import send_mail
# ...
send_mail(
'Feedback from your site, topic: %s' % topic,
message, sender,
['administrator@example.com']
)
send_mail方法有四个必须的参数:主题,邮件正文,from和一个接受者列表。send_mail是Django的EmailMessage类的一个方便的包装,EmailMessage类提供了更高级的方法,比如附件,多部分邮件,以及对于邮件头部的完整控制。 发送完邮件之后,我们会把用户重定向到确认的页面。完成之后的视图方法如下:
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.core.mail import send_mail
from forms import ContactForm
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
topic = form.clean_data['topic']
message = form.clean_data['message']
sender = form.clean_data.get('sender', 'noreply@example.com')
send_mail(
'Feedback from your site, topic: %s' % topic,
message, sender,
['administrator@example.com']
)
return HttpResponseRedirect('/contact/thanks/')
else:
form = ContactForm()
return render_to_response('contact.html', {'form': form})

在POST之后立即重定向
在一个POST请求过后,如果用户选择刷新页面,这个请求就重复提交了。这常常会导致我们不希望的行为,比如重复的数据库记录。在POST之后重定向页面是一个有用的模式,可以避免这样的情况出现:在一个POST请求成功的处理之后,把用户导引到另外一个页面上去,而不是直接返回HTML页面。

自定义校验规则
假设我们已经发布了反馈页面,email已经开始源源不断地涌入了。只有一个问题:一些email只有寥寥数语,很难从中得到什么详细有用的信息。所以我们决定增加一条新的校验:来点专业精神,最起码写四个字,拜托。
我们有很多的方法把我们的自定义校验挂在Django的form上。如果我们的规则会被一次又一次的使用,我们可以创建一个自定义的字段类型。大多数的自定义校验都是一次性的,可以直接绑定到form类。
我们希望message字段有一个额外的校验,我们增加一个clean_message方法:
class ContactForm(forms.Form):
topic = forms.ChoiceField(choices=TOPIC_CHOICES)
message = forms.CharField(widget=forms.Textarea())
sender = forms.EmailField(required=False)
def clean_message(self):
message = self.clean_data.get('message', '')
num_words = len(message.split())
if num_words < 4:
raise forms.ValidationError("Not enough words!")
return message
这个新的方法将在默认的字段校验器之后被调用(在本例中,就是CharField的校验器)。因为字段数据已经被部分地处理掉了,我们需要从form的clean_data字典中把它弄出来。
我们简单地使用了len()和split()的组合来计算单词的数量。如果用户输入了过少的词,我们扔出一个ValidationError。这个exception的错误信息会被显示在错误列表里。
在函数的末尾显式地返回字段的值非常重要。我们可以在我们自定义的校验方法中修改它的值(或者把它转换成另一种Python类型)。如果我们忘记了这一步,None值就会返回,原始的数据就丢失掉了。

自定义视感
修改form的显示的最快捷的方式是使用CSS。错误的列表可以做一些视觉上的增强,<ul>标签的class属性为了这个目的。下面的CSS让错误更加醒目了:
<style type="text/css">
ul.errorlist {
margin: 0;
padding: 0;
}
.errorlist li {
background-color: red;
color: white;
display: block;
font-size: 10px;
margin: 0 0 3px;
padding: 4px 5px;
}
< /style>
虽然我们可以方便地使用form来生成HTML,可是默认的渲染在多数情况下满足不了我们的应用。{{form.as_table}}和其它的方法在开发的时候是一个快捷的方式,form的显示方式也可以在form中被方便地重写。
每一个字段部件(<input type=”text”>, <select>, <textarea>, 或者类似)都可以通过访问{{form.字段名}}进行单独的渲染。任何跟字段相关的错误都可以通过{{form.fieldname.errors}}访问。我们可以同这些form的变量来为我们的表单构造一个自定义的模板:
<form action="." method="POST">
< div class="fieldWrapper">
{{ form.topic.errors }}
< label for="id_topic">Kind of feedback:</label>
{{ form.topic }}
< /div>
< div class="fieldWrapper">
{{ form.message.errors }}
< label for="id_message">Your message:</label>
{{ form.message }}
< /div>
< div class="fieldWrapper">
{{ form.sender.errors }}
< label for="id_sender">Your email (optional):</label>
{{ form.sender }}
< /div>
< p><input type="submit" value="Submit"></p>
< /form>
{{ form.message.errors }}会在<ul class="errorlist">里面显示,如果字段是合法的,或者form没有被绑定,就显示一个空字符串。我们还可以把 form.message.errors 当作一个布尔值或者当它是list在上面做迭代:
<div class="fieldWrapper{% if form.message.errors %} errors{% endif %}">
{% if form.message.errors %}
< ol>
{% for error in form.message.errors %}
< li><strong>{{ error|escape }}</strong></li>
{% endfor %}
< /ol>
{% endif %}
{{ form.message }}
< /div>
在校验失败的情况下, 这段代码会在包含错误字段的div的class属性中增加一个”errors”,在一个有序列表中显示错误信息。

从模型创建表单
我们弄个有趣的东西吧:一个新的form,提交一个新出版商的信息到我们第五章的book应用。
一个非常重要的Django的开发理念就是不要重复你自己(DRY)。Any Hunt和Dave Thomas在《实用主义程序员》里定义了这个原则:在系统内部,每一条(领域相关的)知识的片断都必须有一个单独的,无歧义的,正式的表述。
我们的出版商模型拥有一个名字,地址,城市,州(省),国家和网站。在form中重复这个信息无疑违反了DRY原则,我们可以使用一个捷径:form_for_model():
from models import Publisher
from django.newforms import form_for_model
PublisherForm = form_for_model(Publisher)
PublisherForm是一个Form子类,像刚刚手工创建的ContactForm类一样。我们可以像刚才一样使用它:
from forms import PublisherForm
def add_publisher(request):
if request.method == 'POST':
form = PublisherForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/add_publisher/thanks/')
else:
form = PublisherForm()
return render_to_response('books/add_publisher.html', {'form': form})
add_publisher.html文件几乎跟我们的contact.html模板一样,所以不赘述了。记得在URLConf里面加上:
(r'^add_publisher/$', 'mysite.books.views.add_publisher') 。
还有一个快捷的方法。因为从模型而来的表单经常被用来把新的模型的实例保存到数据库,从form_for_model而来的表单对象包含一个save()方法。一般情况下够用了,你想对提交的数据作进一步的处理的话,无视它就好了。
form_for_instance()是另外一个方法,用于从一个模型对象中产生一个初始化过的表单对象,
这个当然给“编辑”表单提供了方便。

django多表查询

表结构定义如下:

from django.contrib.auth.models import User

class Project(models.Model):

name=models.CharField(maxlength=200, unique=True, db_index=True,null=False)

member=models.ManyToManyField(User)

owner=models.ForeignKey(User,related_name='owner')

description=models.CharField(maxlength=500,null=True)

insert_data=models.DateTimeField(auto_now_add=True)

如果我现在知道一个User.username我想查询这个user所有的project,这个用django到orm怎么来实现,我在网上看到有下面的这种写法,但是不太明白如何解释:

假设我有两个表(model),分别叫useraccount和userrole:

class UserAccount(meta.Model):

person = meta.ForeignKey(Person, core=True)

account = meta.ForeignKey(User, core=True)

class UserRole(meta.Model):

account = meta.ForeignKey(UserAccount, core=True)

group = meta.ForeignKey(Group, core=True)

active = meta.BooleanField(_('Active?'), default=True)

如果我知道useraccount中某个字段(field)的值,那么我就能取到相应的userrole:

userroles.get_object(account__person__id__exact=xxx)

userroles.get_object(account__account__id__exact=xxx)

userroles.get_object(account__id__exact=xxx)

这似乎不是什么技巧,但是我以前确实没想到,既然有同事在codereview中给我指出来,记下来以后改进。

谢谢!

在与已有数据库集成的时候,外键的设置方法:

当你在使用已有的数据库,即是先有数据库表,然后使用python manage.py inspectdb 生成的models.py

文件,为了进行多表联合查询,可以使用Foreignkey来在models文件中进行进行设置,比如说:

class Test():

id=models.IntergerField(primarykey=true)

user = models.ForeignKey(User, core=True)

class User():

user_id=models.IntergerField(primarykey=true)

user_name=models.CharField(maxlength=500,null=True)

这样的话,我们在别处就可以通过Test.user_id来访问User的主键:

result=Test.objects.get(id=1)

result.user_id 是可以的

result.user.user_id也是可以的。

有一点比较奇怪,也是笔者不太明白的是,如果要在对Test对象进行查询的时候,对user_id进行限制的话,不能用点操作符了,而必须使用

双下划线,比如说要取user_id等于1的Test对象,则使用下面的语句:

Test.objects.filter(user__user_id=1)

分析可以发现,在查询的条件当中,所有的这种上下级的操作符都是双下划线,比如说__gt __lt __year __month 再到这里的user__user_id

上面的都是凭回忆写的,如有不当还请指正!

参考自:http://hi.baidu.com/whucsxu/blog/item/070a40d9bf2883c3b7fd48a9.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值