django入門基礎

来源:http://www.cnblogs.com/Jeffding/archive/2017/12/02/7881489.html
-Advertisement-
Play Games

首先要說的是django與其他的框架不同,django是一個封裝的及其完善的框架,我們使用django也不會像之前寫學生系統那樣,django操作資料庫使用自帶的ORM來進行操作,Torando與Flask的資料庫使用就很自由(當然也可以使用我們之前的SQL helper),並且Flask的模板都不 ...


  首先要說的是django與其他的框架不同,django是一個封裝的及其完善的框架,我們使用django也不會像之前寫學生系統那樣,django操作資料庫使用自帶的ORM來進行操作,Torando與Flask的資料庫使用就很自由(當然也可以使用我們之前的SQL helper),並且Flask的模板都不是自帶的而是使用的第三方插件。

  首先創建一個工程:

django-admin startproject mysite

  創建一個應用:

python manage.py starapp app01

  每一個新建的app下都有幾個文件:

  migrations文件夾,存放資料庫的相關信息;

  admin.py文件,Django自帶後臺管理相關配置;

  modals.py,ORM的相關操作;

  tests.py,單元測試;

  views文件夾或者文件,業務處理。

  路由系統

  之前的學生系統傳遞nid都是通過url進行傳遞,這樣導致鏈接的seo權重比較低,所以我們可以進行簡單的優化。

  動態路由:當一條url被路由url(r'^edit/(\w+)/', views.edit)匹配到,那麼在視圖函數中定義的函數就要傳入額外的參數來盛放被正則匹配到的值。

#url
url(r'^edit/(\w+)/(\w+)/', views.edit)
#視圖函數
def edit(request,a1,a2):
    print(a1)
    print(a2)
    return HttpResponse('...')

  上面的例子是順序傳參,當然也可以指定傳參,

#指定傳參
url(r'^edit/(?P<a2>\w+)/(?P<a1>\w+)/', views.edit)
#視圖函數
def edit(request,a2,a1):
    print(a1)
    print(a2)
    return HttpResponse('...')

  註:這兩種傳參方式不可以混著用,與函數傳參不同的是此處的傳參不可以用*args和**kwargs接收。

  偽靜態:

終止符:
^edit$
偽靜態:
url(r'^edit/(\w+).html$', views.edit),

  路由分發

  為了防止不同業務線(app)的開發過程中出現的名稱重覆,所以才有了路由分發的必要性。

from django.conf.urls import url,include
urlpatterns = [
    url(r'^app01/', include('app01.urls')),]

  這樣路由進來就被分發到app01裡面的urls進行進一步路由匹配。

  別名與反向生成url

url(r'^edit/(\w+)/(\w+)/', views.edit,name='n2') #name就是別名
#在視圖函數中:
from django.urls import reverse
v = reverse('n2',args=(1111,))
#url要是指定傳參,reverse里就要用kwargs存放字典指定返回值。

  反生成url可應用在html頁面中,

#url(r'^login/', views.login,name='m1'),
# def login(request):
#     return render(request,'login.html')
#login.html
<form method="POST" action="{% url "m1" %}">
        <input />

  這裡的{% url "m1" %}會被渲染成能被^login/匹配的地址。

  url(r'^edit/(\w+)/', views.edit,name='n2'),

  {% url "n2" i %}與/edit/{{ i }}/一樣,這裡n2先被替換成正則前半部分,後面匹配的部分由i傳參進去。

  ORM框架

  ORM一般用來做原生資料庫語句轉換,使我們開發更為高效。ORM不僅可以進行數據行的增刪改查操作,還可以創建,修改,刪除數據表(所以功能很強大,可以完成大部分的資料庫操作)。

  註:python沒有辦法創建資料庫,只能是連接資料庫。

  ORM利用pymysql等第三方工具連接資料庫(不能直接鏈接資料庫,並且預設不是連接MySQL而是SQLlite)。而且預設鏈接MySQL的是MySQLDB模塊。python3預設沒裝MySQLDB模塊,所以最方便就是更改它預設連接MySQL的配置。

#預設
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
#連接MySQL
DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME':'dbname',
    'USER': 'root',
    'PASSWORD': 'xxx',
    'HOST': '',
    'PORT': '',
    }
}

  最後,我們還需要更改project下麵的init,

import pymysql
pymysql.install_as_MySQLdb()

  這樣我們就可以使用ORM操作pymysql連接MySQL資料庫了。

  models文件中創建數據表的各項屬性:

from django.db import models
class UserInfo(models.Model):#必須繼承
    """
    員工
    """
    nid = models.BigAutoField(primary_key=True)#自增可不寫
    user = models.CharField(max_length=32)
    password = models.CharField(max_length=64)#位數也很重要
    age = models.IntegerField(default=1)

  接著要在INSTALLED_APPS[]裡加入我們註冊的app名。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'mysite',
]
INSTALLED_APPS

  最後一步,在終端輸入

python manage.py makemigrations
python manage.py migrate

  再去查看資料庫就會增加很多表,其中app01_userinfo才是我們剛纔創建的那張表。

  這兩行操作就是在app下migrations生成配置文件相關操作,migrate拿著配置信息去資料庫進行相關操作。

  以後我們要是修改表的名字就直接修改類,然後再次在終端執行這兩條命令即可,當然比如要增加一行數據(例如UserInfo表裡的最後一行age),如果之前有數據,之前的數據可沒有age參數,那該怎麼辦呢,要麼把這行數據設置為null允許為空,要麼就設置預設值。

  外鍵創建

class UserGroup(models.Model):
    """
    部門
    """
    title = models.CharField(max_length=32)
class UserInfo(models.Model):
    """
    員工
    """
    nid = models.BigAutoField(primary_key=True)
    user = models.CharField(max_length=32)
    password = models.CharField(max_length=64)
    age = models.IntegerField(default=1)
    # ug_id
    ug = models.ForeignKey("UserGroup",null=True)

        ug = models.ForeignKey("UserGroup",null=True)預設在資料庫中多出來的數據是ug_id。

  ORM的增刪改查

  增

models.UserGroup.objects.create(title='銷售部')

  查

group_list = models.UserGroup.objects.all()#所有
group_list = models.UserGroup.objects.filter(id=1)#過濾
group_list = models.UserGroup.objects.filter(id__gt=1)#神奇的雙下劃線

  刪

models.UserGroup.objects.filter(id=2).delete()

  更新

models.UserGroup.objects.filter(id=2).update(title='公關部')
# 資料庫相關操作
def index(request):
    # 增刪改查
    from app01 import models
    # 新增
    # models.UserGroup.objects.create(title='銷售部')
    # models.UserInfo.objects.create(user='root',password='pwd',age=18,ug_id=1)
    # 查找
    # group_list = models.UserGroup.objects.all()
    # group_list = models.UserGroup.objects.filter(id=1)
    # group_list = models.UserGroup.objects.filter(id__gt=1)
    # group_list = models.UserGroup.objects.filter(id__lt=1)

    # 刪除
    # models.UserGroup.objects.filter(id=2).delete()

    # 更新
    models.UserGroup.objects.filter(id=2).update(title='公關部')

    # group_list QuerySet類型(列表)
    # QuerySet類型[obj,obj,obj]
    # print(group_list)
    # for row in group_list:
    #     print(row.id,row.title)
    # models.UserInfo.objects.all()


    group_list = models.UserGroup.objects.all()
    return render(request,'newindex.html',{"group_list": group_list})
Views.py

  這裡我們查找的group_list是形似列表的QuerySet類型。QuerySet類型可以理解為[obj,obj,obj]。

for row in group_list:
    print(row.id,row.title)

  同理在前端一樣適用

{% for row in group_list %}
    <li>{{ row.id }} === {{ row.title }}</li>
{% endfor %}

   ORM之連表操作

  我們之前的兩張表,通過外鍵連接,其中ut直接連接UserType,ut代指了usertype的一行數據,我們可以直接使用ut.title直接跨表查詢。

from django.db import models
class UserType(models.Model):
    """
    用戶類型
    """
    title = models.CharField(max_length=32)

class UserInfo(models.Model):#必須繼承
    """
    員工
    """
    id = models.BigAutoField(primary_key=True)#自增可不寫
    name = models.CharField(max_length=32)
    age = models.IntegerField(default=1)
    # ug_id
    ut = models.ForeignKey("UserType",null=True)#外鍵操作
#創建用戶數據
from app01 import models
def test(request):
    # 創建數據
    # models.UserType.objects.create(title='普通用戶')
    # models.UserType.objects.create(title='二逼用戶')
    # models.UserType.objects.create(title='牛逼用戶')
    #不要重覆添加
    # models.UserInfo.objects.create(name='方',age=18,ut_id=1)
    # models.UserInfo.objects.create(name='由',age=18,ut_id=2)
    # models.UserInfo.objects.create(name='劉',age=18,ut_id=2)
    # models.UserInfo.objects.create(name='陳',age=18,ut_id=3)
    # models.UserInfo.objects.create(name='王',age=18,ut_id=3)
    # models.UserInfo.objects.create(name='楊',age=18,ut_id=1)
    return HttpResponse('...')
創建數據表的數據
# 獲取
# result取到的是QuerySet[obj,obj,obj]
result = models.UserInfo.objects.all()
for obj in result:
    print(obj.name,obj.age,obj.ut_id,obj.ut.title)#直接就連表取到值
直接跨表
# UserInfo,ut是FK欄位 - 正向操作  PS: 一個用戶只有一個用戶類型
obj = models.UserInfo.objects.all().first()#取出第一個queryset數據
print(obj.name,obj.age,obj.ut.title)#因為obj只是一個數據只能對應一種用戶
正向跨表
# UserType, 表名小寫_set.all()  - 反向操作   PS: 一個用戶類型下可以有很多用戶
obj = models.UserType.objects.all().first()
print('用戶類型',obj.id,obj.title)
for row in obj.userinfo_set.all():#obj.userinfo_set里是userinfo的query對象,.all()取出所有數據
    print(row.name,row.age)
反向跨表
#反向取出每一行的queryset
result = models.UserType.objects.all()
for item in result:#相當於取出每一行用戶類型對應的用戶的queryset
    for i in item.userinfo_set.all():
        print(i.name)
#過濾每一行
result = models.UserType.objects.all().filter(id= 1 )#<QuerySet [<UserType: UserType object>]>
for item in result:
    print(item.userinfo_set.filter(id =1))#<QuerySet [<UserInfo: UserInfo object>]>
反向跨表補充
result = models.UserInfo.objects.all().values('id','name')#只取兩列
# 並且每列的QuerySet[{'id':'xx','name':'xx'} ]都是這樣的字典
for row in result:
    print(row)
result2 = models.UserInfo.objects.all().first()
print(result2)#UserInfo object
字典取值
result = models.UserInfo.objects.all().values_list('id','name')
# QuerySet[(1,'f'), ]
for row in result:
    print(row)
元組取值
當取出的queryset裡面是obj對象的時候,可以直接在for迴圈里跨表,但是當取出的queryset里是字典或者元祖對象的時候,那麼在for迴圈里就不可以跨表了,這時候就要使用神奇的雙下劃線
models.UserInfo.objects.filter(id__gt=1).values('id','name')#可以取到id>1的queryset對象。
# [{id:1,name:fd},{id:1,name:fd},{id:1,name:fd},]
# models.UserInfo.objects.all().values('id','name')
# models.UserInfo.objects.filter(id__gt=1).values('id','name')
# 無法跨表
# result = models.UserInfo.objects.all().values('id','name')
# for item in result:
#     print(item['id'],item['name'])
# 誇表  __
# result = models.UserInfo.objects.all().values('id','name',"ut__title")
# for item in result:
#     print(item['id'],item['name'],item['ut__title'])
# [(1,df),(2,'df')]
# models.UserInfo.objects.all().values_list('id','name')
# models.UserInfo.objects.filter(id__gt=1).values_list('id','name')
# 無法跨表
# result = models.UserInfo.objects.all().values_list('id','name')
# for item in result:
#     print(item[0],item[1])
# 誇表  __
# result = models.UserInfo.objects.all().values_list('id','name',"ut__title")
# for item in result:
#     print(item[0],item[1],item[2])
神奇的雙下劃線
    v = models.UserInfo.objects.values('id','name') # 6
    v = models.UserInfo.objects.values('id','name','ut__title') # 6
    # select * from userinfo left join usertype

    v1 = models.UserType.objects.values('id','title')
    print(v1) # 4
    v2 = models.UserType.objects.values('id','title','userinfo__name')
    print(v2) #7
    # select  * from usertype left join userinfo
#正向跨表與反向跨表與left join類似,誰在前面就是查他的所有,沒有匹配到的那一行值為none填充
正:
1. q = UserInfo.objects.all().first()
    q.ug.title
2. 
     UserInfo.objects.values('nid','ug_id')              
     UserInfo.objects.values('nid','ug_id','ug__title')  
3. UserInfo.objects.values_list('nid','ug_id','ug__title')
反:
1. 小寫的表名_set
     obj = UserGroup.objects.all().first()
   result = obj.userinfo_set.all() [userinfo對象,userinfo對象,]
                   
2. 小寫的表名
     v = UserGroup.objects.values('id','title')          
     v = UserGroup.objects.values('id','title','小寫的表名稱')          
     v = UserGroup.objects.values('id','title','小寫的表名稱__age')          
                    
3. 小寫的表名
     v = UserGroup.objects.values_list('id','title')          
     v = UserGroup.objects.values_list('id','title','小寫的表名稱')          
     v = UserGroup.objects.values_list('id','title','小寫的表名稱__age') 
正向:
xxxx.filter(ut__title='超級用戶').values('id','name','ut__title')
反向:
xxxx.filter(表名稱__title='超級用戶').values('id','name','表名稱__title')
# 1.增刪改查
# 2. 一般:
    # models.UserInfo.objects.filter(id__gt=1)
    # models.UserInfo.objects.filter(id__lt=1)
    # models.UserInfo.objects.filter(id__lte=1)
    # models.UserInfo.objects.filter(id__gte=1)
    # models.UserInfo.objects.filter(id__in=[1,2,3])
    # models.UserInfo.objects.filter(id__range=[1,2])
    # models.UserInfo.objects.filter(name__startswith='xxxx')
    # models.UserInfo.objects.filter(name__contains='xxxx')
    # models.UserInfo.objects.exclude(id=1)
# 3. 排序
    user_list = models.UserInfo.objects.all().order_by('-id','name')

# 4. 分組
    from django.db.models import Count,Sum,Max,Min
    # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id'))
    # print(v.query)
    # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)
    # print(v.query)having
    # v =models.UserInfo.objects.filter(id__gt=2).values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)
    # print(v.query)where
    


# 5. F,更新時用於獲取原來的值
    # from django.db.models import F,Q
    # models.UserInfo.objects.all().update(age=F("age")+1)

# 6. Q,用於構造複雜查詢條件
    # 應用一:
            # models.UserInfo.objects.filter(Q(id__gt=1))
            # models.UserInfo.objects.filter(Q(id=8) | Q(id=2))
            # models.UserInfo.objects.filter(Q(id=8) & Q(id=2))
    # 應用二:
            # q1 = Q()
            # q1.connector = 'OR'
            # q1.children.append(('id__gt', 1))
            # q1.children.append(('id', 10))
            # q1.children.append(('id', 9))
            #
            #
            # q2 = Q()
            # q2.connector = 'OR'
            # q2.children.append(('c1', 1))
            # q2.children.append(('c1', 10))
            # q2.children.append(('c1', 9))
            #
            # q3 = Q()
            # q3.connector = 'AND'
            # q3.children.append(('id', 1))
            # q3.children.append(('id', 2))
            # q2.add(q3,'OR')
            #
            # con = Q()
            # con.add(q1, 'AND')
            # con.add(q2, 'AND')
            # (id=1 or id = 10 or id=9 or (id=1 and id=2)) and (c1=1 or c1=10 or c1=9)
            # models.UserInfo.objects.filter(con)
    # condition_dict = {
    #     'k1':[1,2,3,4],
    #     'k2':[1,],
    # }
    # con = Q()
    # for k,v in condition_dict.items():
    #     q = Q()
    #     q.connector = 'OR'
    #     for i in v:
    #         q.children.append(('id', i))
    #     con.add(q,'AND')
    # models.UserInfo.objects.filter(con)

# 7. extra, 額外查詢條件以及相關表,排序

    models.UserInfo.objects.filter(id__gt=1)
    models.UserInfo.objects.all() 
    # id name age ut_id


    models.UserInfo.objects.extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
    # a. 映射
        # select 
        # select_params=None
        # select 此處 from 表
    
    # b. 條件
        # where=None
        # params=None,
        # select * from 表 where 此處
    
    # c. 表
        # tables
        # select * from 表,此處
        
    # c. 排序
        # order_by=None
        # select * from 表 order by 此處
    
    
    models.UserInfo.objects.extra(
        select={'newid':'select count(1) from app01_usertype where id>%s'},
        select_params=[1,],
        where = ['age>%s'],
        params=[18,],
        order_by=['-age'],
        tables=['app01_usertype']
    )
    """
    select 
        app01_userinfo.id,
        (select count(1) from app01_usertype where id>1) as newid
    from app01_userinfo,app01_usertype
    where 
        app01_userinfo.age > 18
    order by 
        app01_userinfo.age desc
    """
    
    result = models.UserInfo.objects.filter(id__gt=1).extra(
        where=['app01_userinfo.id < %s'],
        params=[100,],
        tables=['app01_usertype'],
        order_by=['-app01_userinfo.id'],
        select={'uid':1,'sw':"select count(1) from app01_userinfo"}
    )
    print(result.query)
    # SELECT (1) AS "uid", (select count(1) from app01_userinfo) AS "sw", "app01_userinfo"."id", "app01_userinfo"."name", "app01_userinfo"."age", "app01_userinfo"."ut_id" FROM "app01_userinfo" , "app01_usertype" WHERE ("app01_userinfo"."id" > 1 AND (app01_userinfo.id < 100)) ORDER BY ("app01_userinfo".id) DESC

# 8. 原生SQL語句

    from django.db import connection, connections
    
    cursor = connection.cursor() # connection=default數據
    cursor = connections['db2'].cursor()
    
    cursor.execute("""SELECT * from auth_user where id = %s""", [1])
    
    row = cursor.fetchone()
    row = cursor.fetchall()
    
    
    - extra
    - 原生SQL語句
    - raw
        result = models.UserInfo.objects.raw('select * from userinfo')
        [obj(UserInfo),obj,]
        result = models.UserInfo.objects.raw('select id,1 as name,2 as age,4 as ut_id from usertype')
        [obj(UserInfo),obj,]
        
        v1 = models.UserInfo.objects.raw('SELECT id,title FROM app01_usertype',translations=name_map)
        
# 9. 簡單的操作
    http://www.cnblogs.com/wupeiqi/articles/6216618.html
Django ORM操作
# """
    #     select
    #         id,
    #         name,
    #         (select count(1) from tb) as n
    #     from xb where ....
    # """
    #
    # v = models.UserInfo.objects.all().extra(
    #     select={
    #         'n':"select count(1) from app01_usertype where id=%s or id=%s",
    #         'm':"select count(1) from app01_usertype where id=%s or id=%s",
    #     },
    #     select_params=[1,2,3,4])
    # for obj in v:
    #     print(obj.name,obj.id,obj.n)

    # models.UserInfo.objects.extra(
    #     where=["id=1","name='alex'"]
    # )
    # models.UserInfo.objects.extra(
    #     where=["id=1 or id=%s ","name=%s"],
    #     params=[1,"alex"]
    # )

    # models.UserInfo.objects.extra(
    #     tables=['app01_usertype'],
    # )
    # """select * from app01_userinfo,app01_usertype"""


    # result = models.UserInfo.objects.filter(id__gt=1)
    # print(result.query)
    # result = models.UserInfo.objects.filter(id__gt=1).extra(
    #     where=['app01_userinfo.id < %s'],
    #     params=[100,],
    #     tables=['app01_usertype'],
    #     order_by=['-app01_userinfo.id'],
    #     select={'uid':1,'sw':"select count(1) from app01_userinfo"}
    # )
    # print(result.query)

    # v = models.UserInfo.objects.all().order_by('-id','name')
    # v = models.UserInfo.objects.all().order_by('-id','name').reverse()#只有加order by才可以用reverse
    # v = models.UserInfo.objects.all().order_by('id','-name')
    # print(v)

    # v = models.UserInfo.objects.all()
    # [obj]
    # v = models.UserInfo.objects.all().only('id','name')#只拿id,only,還是obj,能取到age但是不要用only還去取,因為每次取都增加一次查詢
    # v = models.UserInfo.objects.all().defer('name')#除了name以外的數據
    # # [obj]
    # for obj in v:
    #     obj.id,obj.name
    # models.UserInfo.objects.values('id','name')
    # [{id,nam}]

    # models.UserInfo.objects.all().using('db2')#指定去哪個資料庫取

    # models.UserInfo.objects.all().filter().all().exclude().only().defer()

    # models.UserInfo.objects.none()
    # result = models.UserInfo.objects.aggregate(k=Count('ut_id', distinct=True), n=Count('id'))
    # print(result)

    # v = models.UserInfo.objects.all().first()
    # # models.UserInfo.objects.get(id=1)
    #
    # obj = models.UserType.objects.create(title='xxx')
    # obj = models.UserType.objects.create(**{'title': 'xxx'})
    # print(obj.id)
    #
    # obj = models.UserType(title='xxx')
    # obj.save()


    # objs = [
    #     models.UserInfo(name='r11'),
    # ]
    # models.UserIn

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • #log4j.rootLogger=Debug,consolelog4j.rootLogger=info,console#控制台輸出 log4j.appender.console=org.apache.log4j.ConsoleAppenderlog4j.appender.console.layou ...
  • 設想從一大群選手中挑選人員組建一支隊伍,每名選手都擁有特定的技能組合。目標是組建出一隻最小的隊伍,使得隊伍整體擁有一組特定的技能組合。也就是說,對於隊伍整體所需要的技能,隊伍中至少有一名選手必須擁有這項技能。假定S為隊伍所必須擁有的技能集合,P為所有待選選手的技能集合。從P中挑選出一些技能組合以構成... ...
  • 看見頭文件中的條件編譯就犯怵,不知什麼意思,但是,師傅說:”就得那麼寫“,我照做,但是知其然而不知其所以然。 好吧,我承認自己只是一個代碼的搬運工,哦,不,或許還談不上。 下麵是學習後自己的理解~~~ 代碼: 也許我渣把,總之,之前我確實不會。 解釋: 第1、2行和第14行:防止重覆定義。 如果兩個 ...
  • import time# print(help(time)) # 顯示time模塊全文本# Functions: # 執行結果 # time() -- return current time in seconds since the Epoch as a float # 以浮點數返回以秒計算的從19 ...
  • Mojo: Maven plain Old Java Object 1、插件命名規則:maven-<yourplugin>-plugin是Maven的保留欄位,不允許使用,我們可以用<myplugin>-maven-plugin來命名自己開發的插件。 2、自定義插件代碼,註意pom文件的packag ...
  • java學習資料,僅供學習交流,自行取用↓ 鏈接:https://pan.baidu.com/s/1dF1wCST 密碼:i75g ...
  • 創建原型模板 1、在空目錄運行archetype:generate上面的命令,待下載完必要的jar包後,首先需要輸入內置的原型編號; 2、輸入任意編號後,繼續下載必要jar包,之後要求分別輸入groupId,artifactId,version,package,並確認 3、瀏覽Maven工程 4、內 ...
  • 在php官方文檔里有這麼一段: 代碼輸出結果如下: I am bar.I am bar.. 結果輸出了: I am bar.I am bar.you yyy. 確認 $foo->$baz[2] 即為 $foo->baz, 同理 $foo->$baz[1] 即 $foo->bar, 那麼第八行這裡 $ ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...