Django 基礎(二),Model連表、Form自定義錯誤信息、Ajax操作

一、Model連表操作


一對一和一對多

表結構如下:

class user_type(models.Model):
    name = models.CharField(max_length=50)

class user(models.Model):
    username = models.CharField(max_length=50)
    password = models.CharField(max_length=50)
    email = models.EmailField()
    usertype = models.ForeignKey(user_type)
    
user.objects.filter(usertype__id = 1).values('username')

示例

# 查詢user表中,用戶類型爲管理員的所有用戶
data = user.objects.filter(usertype__name = '管理員')

# 取單字段(比如只取username字段)
data = user.objects.filter(usertype__name = '管理員').values('username')

# 大於條件
data = user.objects.filter(usertype__id__gt=3)

這裏通過__(雙下劃線)表示連表查詢,比如usertype__name相當於操作到了user_type表的name字段。


多對多關係

表結構如下:

class user(models.Model):
    username = models.CharField(max_length=50)
    password = models.CharField(max_length=50)
    email = models.EmailField()
    usertype = models.ForeignKey(user_type)
    
class groups(models.Model):
    gname = models.CharField(max_length=255)
    guser = models.ManyToManyField('user')
user_obj = models.user.objects.get(name=u'tuchao')
user_objs = models.user.objects.all()
 
group_obj = models.groups.objects.get(gname='dev')
group_objs = models.groups.objects.all()
 
# 添加數據
#group_obj.guser.add(user_obj)
#group_obj.guser.add.add(*user_objs)
 
# 刪除數據
#group_obj.guser.remove(user_obj)
#group_obj.guser.remove(*user_objs)
 
 
# 這裏有點繞,用戶表的對象.組表的名稱(與用戶相關係的表其中有定義與用戶表的多對多關係)_set.add(組表的對象)

# 添加數據
#user_obj.groups_set.add(group_obj)
#user_obj.groups_set.add(*group_objs)
 
# 刪除數據
#user_obj.groups_set.remove(group_obj)
#user_obj.groups_set.remove(*group_objs)
 
# 獲取數據
#print group_obj.guser.all()
#print group_obj.guser.all().filter(id=1)
 
# 獲取數據
#print user_obj.groups_set.all()
#print user_obj.groups_set.all().filter(gname='tuchao')
#print user_obj.groups_set.all().filter(gname='tyz')


# 使用MySQL事務的方式完成多對多關係的數據插入,當使用事務方式的時候,在同一個事務中的語句要麼全部執行成功,要麼一個都不會執行,保證了數據的完整性。

#導入相關庫
from django.db import connection,transaction

try:
    ''' 啓動事務 '''
    with transaction.atomic():
    ''' 先給用戶信息表插入數據 '''
        user.objects.create(username=username,password=password,realname=realname,email=email,ugid=group_id)
    ''' 然後通過用戶名獲取該條記錄的數據,取出對應關係的ID值插入到關係表 '''    
        d1 = user.objects.get(username=username)
        uuid = d1.uid
        ugid = d1.ugid
        userandgroup.objects.create(gid=ugid,uid=uuid)
except Exception,err:
    print (err)


二、Form 創建自定義錯誤信息

forms.py的文件

class RegisterForm(forms.Form):
    username = forms.CharField(widget=forms.TextInput(attrs={'class':'user_name','placeholder':'用戶名'}),help_text='100 characters max.')
    password = forms.CharField(widget=forms.PasswordInput(attrs={'class':'pwd','placeholder':'密碼'}))
    real_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder':'真實姓名'}))
    email = forms.CharField(widget=forms.EmailInput(attrs={'placeholder':'Email'}))
    gender = forms.BooleanField()

# 這裏的'placeholder':'用戶名' 是input裏面的參數。 如: <input name="hostname" placeholder="hostname" />
    
    
class AdminHostAdd(forms.Form):
    othername = forms.CharField(widget=forms.TextInput(attrs={'class':'othername'}),error_messages={'required':('業務名不能爲空'),'invalid':'業務名格式錯誤'})
    hostname = forms.CharField(widget=forms.TextInput(attrs={'class':'hostname'}),error_messages={'required':('主機名不能爲空'),'invalid':'主機名格式錯誤'})
    hardconfig = forms.CharField(widget=forms.TextInput(attrs={'class':'hardconfig'}),error_messages={'required':('硬件配置信息不能爲空')})
    wip = forms.IPAddressField(error_messages={'required':('外網IP不能爲空'),'invalid':'IP格式錯誤'})
    lip = forms.IPAddressField(error_messages={'required':('內網IP不能爲空'),'invalid':'IP格式錯誤'})
    
# error_messages:required對應的是當提交內容爲空所提示的信息,invalid則表示提交的數據格式錯誤所提示的信息。       


# 在頁面中輸出自定義錯誤信息


# 在功能函數中截取的部分代碼,獲取自定義錯誤信息
ret = {'data':None,'error':'None'}

ret['data'] = form
firstmessage = form.errors.as_data()
# 將獲取的錯誤信息傳給字典,key爲error
ret['error'] = firstmessage.values()[0][0].messages[0]
# 在輸出信息的時候返回頁面和字典
return render_to_response('admin-host-add.html',ret)

# 在Html中獲取返回的字典數據

<span class="hostaddstatus">{{ error }}</span>


三、學習使用Ajax


Ajax的基本語法

/* 首先引入Jquery  */
<script src="/static/assets/js/jquery-1.12.0.js"></script>
<script type="text/javascript">

function DoAjax(){
    /* 獲取選定元素的數據 */
    var temp = $('#text01').val();
    $.ajax({
       /* 提交請求的url */  
        url:'/ops01/ad/',
      /* 提交請求的方式 */    
        type:'POST',
      /* 返回的數據,key:value */  
        data:{data:temp},
      /* 請求成功所執行的方法 */
        success:function(arg){

            console.log('success');
        },

      /* 請求失敗所執行的方法 */
        error:function(){

            console.log('failed')
        }
    });
}


</script>


功能實戰

實現登陸頁面在沒有登陸的情況下檢測用戶名是否存在,然後通過Ajax實現密碼錯誤檢測和登陸跳轉。

# Python 後端功能代碼實現

#!/usr/local/python27/bin/python2.7
# coding=utf8
# noinspection PyUnresolvedReferences

from django.shortcuts import render
from ops01.forms import RegisterForm,AdminHostAdd,CreateGroups
from django.http import HttpResponse
from django.shortcuts import render_to_response
from ops01.models import *
from django.db import connection,transaction
import json

def Login(request):
    if request.method == 'POST':
        username = request.POST.get('u',None)
        password = request.POST.get('p',None)
        code = request.POST.get('s',None)
        print(username,password,code)
        data = {'statuscode': 0, 'status': 'ok'}
''' 當code=0 時表示檢查用戶名是否存在,當code=1 時表示嘗試登陸'''
        if code == '0':
            un = user.objects.filter(username=username)

            if un:
                return HttpResponse(json.dumps(data))
            else:
                data['statuscode'] = 1
                data['status'] = 'failed'
                return HttpResponse(json.dumps(data))
        else:

            un = user.objects.filter(username=username)
            data = un.values()[0]
            print data.get('password')
            if data.get('password') == password:
                data = {'statuscode': 0, 'status': 'ok'}
                return HttpResponse(json.dumps(data))
            else:
                data['statuscode'] = 1
                data['status'] = 'failed'
                ''' 返回一個json格式的字典數據 '''
                return HttpResponse(json.dumps(data))
    return render_to_response('login.html',{})
/* 前端javascript代碼實現  */

<script src="/static/assets/js/jquery-1.12.0.js"></script>
<script type="text/javascript">

$(function(){

     $('#email').blur(function(){
            var temp = $('#email').val();
            $.ajax({
                url:'/ops01/login/',
                type:'POST',
                /* 將從元素中獲取到的數據傳到後端,這裏的s=0是用於後端代碼判斷前端的需求是要執行檢測用戶名還是要登陸 */
                data:{u:temp,s:0},
                success:function(arg){
        /* 將後端傳過來的字典轉換成javascript能識別的字典 */
                    var obj = jQuery.parseJSON(arg)
           /* 通過後端返回的狀態碼判斷結果,然後通過Jquery更改樣式的方式控制是否顯示之前定義好的提示信息 */         
                    if(obj.statuscode == 1){
                 /*  */   
                        $('#chk_pCn7em').attr({style:"display: inline"})
                        console.log(obj.statuscode)
                    }else{
                        $('#chk_pCn7em').attr({style:"display: none"})
                    }

                },

                error:function(){

                    console.log('failed')
                }
            });

        })

            $('#denglu').click(function(){
            var u = $('#email').val();
            var p = $('#password').val();
            $.ajax({
                url:'/ops01/login/',
                type:'POST',
                data:{u:u,p:p,s:1},
                success:function(arg){
                    var obj = jQuery.parseJSON(arg)
                    if (obj.statuscode == 0){
                    /* 頁面跳轉 */
                        window.location.href='http://localhost/ops01/adminindex/'
                    }else{
                        $('#promptid').attr({style:"display: inline"})
                    }

                },

                error:function(){

                    console.log('failed')
                }
            })

        })


})


/* 提示: 還可以通過設置屬性的方式修改樣式 例如: $('#stipid').attr('class','stip')  */  
/* 修改選中元素的文本內容 $('#stipid').text('創建成功!')  */

</script>

Ajax的好處是整個請求過程是異步的,在不刷新頁面的情況下完成向後端服務器的請求。


通過後端代碼、模版語言、<select>標籤實現靈活的下拉列表

# Python後端代碼

#獲取groups表中的所有數據
gd = groups.objects.all()
return render_to_response('user-add.html',{'form':cuser,'gop':gd})
<!-- Html前端代碼 -->

<p>

    <select name="group_id" class="gse">
    {% for i in gop %}
        <option value="{{ i.gid }}">{{ i.gname }}</option>
    {% endfor %}
    </select>

</p>

<!-- 編寫思路 -->
<!-- 後端會返回一個{ 'gop':gd } 的字典,gd是一個列表裏面保存的是groups表取出來的數據對象,每行數據對應一個對象; gd放入了字典裏,並設置key爲'gop'通過返回字典給前端,前端將可以通過key('gop')得到gd列表,然後通過模版語言循環列表則得到了裏面的每行數據的對象。 -->

<!-- <select>標籤的name屬性是定義返回給後端程序接收的變量名,而<option>標籤中的value則是對應的值。-->


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章