Djangoプロジェクトの実践(モール):11。補足:アドレスの3レベルのリンク

ここに画像の説明を挿入

(先生の生放送の内容によると)

1.準備

  • アプリを作成する:アドレス
D:\pythonprogram\django_project\lgshop\apps> python ..\manage.py startapp addresses
  • アプリを登録する
    ここに画像の説明を挿入

2.3レベルのリンケージデータベース設計に対応

  • 州、市、郡のレベルで住所を保存するには、次の2つの方法があります。
    • 方法1:州、市、郡は3つのテーブルに格納され、外部キーに従って関連付けられます
      ここに画像の説明を挿入
    • 方法2:州、市、郡をテーブルに保存し、外部キーの関連付けを使用してそれらを独自に実装します
      ここに画像の説明を挿入
  • 今回採用した2番目の方法:州、市、郡はテーブルに保存して達成します
# /apps/addresses/models.py
from django.db import models

class Area(models.Model):
    name=models.CharField(max_length=20,verbose_name="名称")
    parent=models.ForeignKey("self",on_delete=models.SET_NULL,null=True,blank=True,verbose_name="上级",related_name="subs")

    class Meta:
        db_table="tb_areas"
        verbose_name="省市区"
        verbose_name_plural=verbose_name

    def __str__(self):
        return self.name
  • データ移行
    ここに画像の説明を挿入
python manage.py makemigrations
python manage.py migrate

三、実現方法

ここに画像の説明を挿入

  • ページが読み込まれると、バックエンドへの州情報のクエリが自動的に開始され、その結果が州のドロップダウンリストに挿入されます。
  • 州情報が変更されると、州IDがバックエンドに送信され、ajaxを介して都市/州のクエリが開始され、結果が都市/州のドロップダウンリストに挿入されます。
  • 市と州の情報が変更されると、市IDがバックエンドに送信され、ajaxを介して地区/郡のクエリが開始され、結果が地区/郡のドロップダウンリストに挿入されます。
  • 州、市、郡の3レベルの連携を実現するために

第四に、州のリストを取得します

1.フロントエンドの実装

  • ページが読み込まれると、バックエンドへの州のクエリが自動的に開始されます
    ここに画像の説明を挿入
    ここに画像の説明を挿入

2.インターフェースの設計と定義

2.1リクエスト方法:

オプション プログラム
リクエスト方法 取得する
リクエストアドレス / areas /

2.2リクエストパラメータ:

パラメータ名 の種類 合格する必要があります 説明
area_id ストリング 番号 空気

2.3応答結果:json

回答結果 回答内容
コード ステータスコード
errmsg エラーメッセージ
Province_list リスト、各要素は辞書です:{"id":province id、 "name":province name}
  • 州データJSON
{
    
    
  "code":"0",
  "errmsg":"OK",
  "province_list":[
      {
    
    
          "id":110000,
          "name":"北京市"
      },
      {
    
    
          "id":120000,
          "name":"天津市"
      },
      {
    
    
          "id":130000,
          "name":"河北省"
      },
      ......
  ]
}

3.バックエンドビューの実装

  • パラメータを取得する
  • パラメータが空の場合は、州の情報を照会することを意味します
    • Areasクラスを介して、親が空のデータセットを取得します
    • データセットを周期的に読み取り、州情報のリストを生成します
      • 州情報辞書:{"id":州ID、 "名前":州名}
    • フロントエンドのjsonデータを返す
      ここに画像の説明を挿入

4.バックエンドルーティングの定義

4.1トータルルーティング

  • lgshop / urls.py
    ここに画像の説明を挿入

4.2サブルート

ここに画像の説明を挿入

第五に、都市リストを取得します

1.フロントエンドの実装

  • 選択した都道府県情報が変更されたら、都道府県IDをバックエンドに送信して市区町村のクエリを開始します
    ここに画像の説明を挿入

2.インターフェースの設計と定義

2.1リクエスト方法:

オプション プログラム
リクエスト方法 取得する
リクエストアドレス / areas /

2.2リクエストパラメータ:

パラメータ名 の種類 合格する必要があります 説明
area_id ストリング 番号 省id

2.3応答結果:json

回答結果 回答内容
コード ステータスコード
errmsg エラーメッセージ
sub_data 辞書
  • 都市データJSON
{
    
    
	"code":"0",
	"errmsg":"OK",
	"sub_data":{
    
    
	  "id":130000,
	  "name":"河北省",
	  "subs":[
	      {
    
    
	          "id":130100,
	          "name":"石家庄市"
	      },
	      ......
	  ]
	}
}

3.バックエンドビューの実装

  • パラメータを取得する
  • パラメータが空でない場合は、市または郡の情報を照会することを意味します
    • Areasクラスを介してid = Provinceidで州情報を取得します
    • Areasクラスを介してparent__id = Provinceidで都市データセットを取得します
    • データセットを周期的に読み取り、州情報のリストを生成します
      • 都市情報辞書:{"id":city id、 "name":city name}
    • subs_dataデータを生成する
    • フロントエンドのjsonデータを返す
      ここに画像の説明を挿入

6.郡のリストを取得します

1.フロントエンドの実装

  • 選択した都市情報が変更されたら、都市IDをバックエンドに送信して、郡のクエリを開始します
    ここに画像の説明を挿入

2.インターフェースの設計と定義

2.1リクエスト方法:

オプション プログラム
リクエスト方法 取得する
リクエストアドレス / areas /

2.2リクエストパラメータ:

パラメータ名 の種類 合格する必要があります 説明
area_id ストリング 番号 都市ID

2.3応答結果:json

回答結果 回答内容
コード ステータスコード
errmsg エラーメッセージ
sub_data 辞書
  • 郡データJSON
{
    
    
	"code": "0", 
	"errmsg": "OK", 
	"sub_data": {
    
    
		"id": 130100, 
		"name": "石家庄市", 
		"subs": [
			{
    
    
				"id": 130102, 
				"name": "长安区"}, 
			},
			......
		]
	}
}

3.バックエンドビューの実装

  • パラメータを取得する
  • パラメータが空でない場合は、市または郡の情報を照会することを意味します
    • Areasクラスを介してid = cityidで都市情報を取得します
    • Areasクラスを介してparent__id = cityidの郡データセットを取得します
    • データセットを周期的に読み取り、郡情報のリストを生成します
      • 郡情報辞書:{"id":郡ID、 "名前":郡名}
    • subs_dataデータを生成する
    • フロントエンドのjsonデータを返す
  • 都市コードによるコードの再利用

7、コードの最適化

  • 州、市、郡のデータは基本的に変更されず、キャッシュに保存してmysqlデータの読み取り回数を増やし、応答速度を向上させることができます。
    • 今回はCACHESのデフォルト領域に保存されました
  • 例外のキャプチャと処理
  • 州、市、郡のデータの有効期限をパラメータ化します

1.説明

  • パラメータを取得する
  • パラメータが空かどうかを確認します
    • パラメータが空の場合は、州の情報を取得します
    • パラメータが空でない場合は、area_idに従って市と郡の情報を取得します
  • 州の情報を取得する:
  • CACHESからprovince_model_listを読み取ります
  • Province_model_listが空の場合、テーブルリクエストに州情報がないか、州情報が無効であるため、mysqlデータベースから読み取る必要があります。
  • データベースにアクセスする必要があるため、読み取りエラーまたは異常エラーが発生する可能性があり、例外キャプチャが必要です。
    • Areasクラスを介して、親が空のデータセットを取得します
    • データセットを周期的に読み取り、州情報のリストを生成します
    • CACHESに州情報を保存する
    • ここに戻る必要はありません。province_model_listが存在するため、これも返す必要があります。
  • 例外が発生した場合は、ログを保存し、エラー情報を含むJSONを返します
  • 州情報を含むJSONを返す
  • 市と郡の情報を取得する
    • CACHESからsub_data + area_id情報を読み取ります
    • sub_data + area_id情報が空の場合、テーブルリクエストに市または郡の情報がないか、市および郡の情報が無効であるため、mysqlデータベースから読み取る必要があります。
    • データベースにアクセスする必要があるため、読み取りエラーまたは異常エラーが発生する可能性があり、例外キャプチャが必要です。
      • Areasクラスを介してid = Provinceidで州情報を取得します
      • Areasクラスを介してparent__id = Provinceidで都市データセットを取得します
      • データセットを周期的に読み取り、州情報のリストを生成します
      • subs_dataデータを生成する
      • 市と郡の情報をCACHESに保存します:sub_data + area_id
    • 例外が発生した場合は、ログを保存し、エラー情報を含むJSONを返します
    • 州情報を含むJSONを返す

2.最適化されたコード

logger = logging.getLogger('django')

class AreasView(View):
   """省市区三级联动"""

   def get(self,request):
       # 判断当前是要查询省份还是市区数据
       area_id=request.GET.get("area_id")
       if not area_id:
           province_list = cache.get('province_list')

           if not province_list:
               # 查询省级数据
               try:
                   province_model_list = Area.objects.filter(parent__isnull=True)  # parent 是外键  parent__null 判断此字段是否为空
                   # print(type(province_model_list),province_model_list)
                   """
                   # 返回省份json数据格式
                   {
                     "code":"0",
                     "errmsg":"OK",
                     "province_list":[
                         {
                             "id":110000,
                             "name":"北京市"
                         },
                         {
                             "id":120000,
                             "name":"天津市"
                         }
                     ]
                   }
                   """
                   province_list=[]

                   for province_model in province_model_list:
                       province_dict={
    
    
                           "id":province_model.id,
                           "name":province_model.name,
                       }
                       province_list.append(province_dict)

                   # 将数据保存到Redis中 默认的
                   # cache.set("province_list", province_list, 3600)
                   cache.set("province_list", province_list, AREA_REDIS_EXPIRES)
               except Exception as e:
                   logger.error(e)
                   return http.JsonResponse({
    
    "code": RETCODE.DBERR, "errmsg": "查询省份数据错误"})
               # return http.JsonResponse({"code": RETCODE.OK, "errmsg": "OK", "province_list": province_list})
           # else:
           return http.JsonResponse({
    
    "code": RETCODE.OK, "errmsg": "OK", "province_list": province_list})
       else:
           # 查询城市或者区域的数据
           sub_data = cache.get("sub_data_" + area_id)
           if not sub_data:
               """
               # 返回市、县json数据格式
                   {
                       "code":"0",
                       "errmsg":"OK",
                       "sub_data":{
                           "id":130000,
                           "name":"河北省",
                           "subs":[
                             {
                                 "id":130100,
                                 "name":"石家庄市"
                             },
                             ......
                           ]
                       }
                   }
                   或
                   {
                       "code": "0", 
                       "errmsg": "OK", 
                       "sub_data": {
                           "id": 130100, 
                           "name": "石家庄市", 
                           "subs": [
                               {
                                   "id": 130102, 
                                   "name": "长安区"}, 
                               },
                               ......
                           ]
                       }
                   }
               """
               try:
                   parent_model=Area.objects.get(id=area_id)
                   sub_model_list = Area.objects.filter(parent__id=area_id)  # parent是Area的外键

                   subs=[]
                   for sub_model in sub_model_list:
                       sub_dict={
    
    
                           "id":sub_model.id,
                           "name":sub_model.name,
                       }
                       subs.append(sub_dict)
                   sub_data={
    
    
                       "id":parent_model.id,
                       "name":parent_model.name,
                       "subs":subs,
                   }
                   # cache.set("sub_data_" + area_id, sub_data, 3600)
                   cache.set("sub_data_" + area_id, sub_data, AREA_REDIS_EXPIRES)
               except Exception as e:
                   logger.error(e)
                   return http.JsonResponse({
    
    "code": RETCODE.DBERR, "errmsg": "查询城市或区县数据错误"})

           return http.JsonResponse({
    
    "code": RETCODE.OK, "errmsg": "OK", "sub_data": sub_data})


おすすめ

転載: blog.csdn.net/laoluobo76/article/details/114274170