一、admin组件使用

  Django 提供了基于 web 的管理工具。

  Django 自动管理工具是 django.contrib 的一部分。你可以在项目的 settings.py 中的 INSTALLED_APPS 看到它:

# Application definition

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

  django.contrib是一套庞大的功能集,它是Django基本代码的组成部分。

1、激活管理工具

  通常我们在生成项目时会在 urls.py 中自动设置好,

from django.conf.urls import url
from django.contrib import admin urlpatterns = [
url(r'^admin/', admin.site.urls),
] from django.contrib import admin
from django.urls import path urlpatterns = [
path('admin/', admin.site.urls),
]

  当这一切都配置好后,Django 管理工具就可以运行了。

2、使用管理工具

  启动开发服务器,然后在浏览器中访问 http://127.0.0.1:8000/admin/,得到登陆界面,你可以通过命令 python manage.py createsuperuser 来创建超级用户。

  为了让 admin 界面管理某个数据模型,我们需要先注册该数据模型到 admin

from django.db import models

# Create your models here.

class Author(models.Model):

    name=models.CharField( max_length=32)
age=models.IntegerField() def __str__(self):
return self.name class Publish(models.Model): name=models.CharField( max_length=32)
email=models.EmailField() def __str__(self):
return self.name class Book(models.Model): title = models.CharField( max_length=32)
publishDate=models.DateField()
price=models.DecimalField(max_digits=5,decimal_places=2) publisher=models.ForeignKey(to="Publish")
authors=models.ManyToManyField(to='Author') def __str__(self):
return self.title

models.py示例

3、admin的定制

  在admin.py中只需要讲Model中的某个类注册,即可在Admin中实现增删改查的功能,如:

from django.contrib import admin
from app01.models import * admin.site.register(UserInfo)
admin.site.register(Book)
admin.site.register(Room)

  但是,这种方式比较简单,如果想要进行更多的定制操作,需要利用ModelAdmin进行操作,如:

方式一:
class UserAdmin(admin.ModelAdmin):
list_display = ('user', 'pwd',) admin.site.register(models.UserInfo, UserAdmin) # 第一个参数可以是列表 方式二:
@admin.register(models.UserInfo) # 第一个参数可以是列表
class UserAdmin(admin.ModelAdmin):
list_display = ('user', 'pwd',)

ModelAdmin中提供了大量的可定制功能,如

1. list_display,列表时,定制显示的列。

# 模板
@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
list_display = ('user', 'pwd', 'xxxxx') def xxxxx(self, obj):
return "xxxxx"

  在MRBS系统上定制admin示例:

class BookConfig(admin.ModelAdmin):
list_display = ["user", "room", "date"] # 不能放多对多字段 admin.site.register(Book, BookConfig) # 定制类继承了ModelAdmin, 但优先显示BookConfig类的,找不到再找父类的

  显示效果:

  

2. list_display_links,列表时,定制列可以点击跳转。

class BookConfig(admin.ModelAdmin):
list_display = ["user", "room", "date"] # 不能放多对多字段
list_display_links = ["room", "date"] # 自由定制哪一列可以做跳转 admin.site.register(Book, BookConfig)

  显示效果:

  

3. list_filter,列表时,定制右侧快速筛选。

class BookConfig(admin.ModelAdmin):
list_display = ["user", "room", "date"] # 不能放多对多字段
list_display_links = ["room", "date"] # 自由定制哪一列可以做跳转
list_filter = ["user", "date"] # 定制右侧快速筛选 admin.site.register(Book, BookConfig)

  显示效果:

  

4. list_select_related,列表时,连表查询是否自动select_related

5. list_editable,列表时,可以编辑的列

class BookConfig(admin.ModelAdmin):
list_display = ["user", "room", "date"] # 不能放多对多字段
list_display_links = ["room", "date"] # 自由定制哪一列可以做跳转
list_filter = ["user", "date"] # 定制右侧快速筛选
list_editable = ["user"] admin.site.register(Book, BookConfig)

  需要注意的是设置为list_editable就不能设置为list_display_links。

  显示效果

  

6. search_fields,列表时,模糊搜索的功能

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin): search_fields = ('user', 'pwd')

  显示效果:

  

7. date_hierarchy,列表时,对Date和DateTime类型进行搜索

class BookConfig(admin.ModelAdmin):
list_display = ["user", "room", "date"] # 不能放多对多字段
list_display_links = ["room", "date"] # 自由定制哪一列可以做跳转
list_filter = ["user", "date"] # 定制右侧快速筛选
list_editable = ["user"]
search_fields = ['date'] date_hierarchy = 'date' admin.site.register(Book, BookConfig)

  显示效果:

  

8. inlines,详细页面,如果有其他表和当前表做FK,那么详细页面可以进行动态增加和删除(不常用)

class UserInfoInline(admin.StackedInline): # TabularInline
extra = 0
model = models.UserInfo class GroupAdminMode(admin.ModelAdmin):
list_display = ('id', 'title',)
inlines = [UserInfoInline, ]

9. action,列表时,定制action中的操作

  自带的action操作是一个批量选中删除的操作:

  

  点击go即完成删除操作。

自定制action的操作:

class BookConfig(admin.ModelAdmin):
...
# 定制Action行为具体方法
def func(self, request, queryset):
print(self, request, queryset)
queryset.update(date="2012-12-12") func.short_description = "批量初始化操作"
actions = [func, ] # Action选项都是在页面上方显示
actions_on_top = True
# Action选项都是在页面下方显示
actions_on_bottom = False # 是否显示选择个数
actions_selection_counter = True admin.site.register(Book, BookConfig)

  点选并选择批量初始化后,显示效果如下:

  

10. 定制HTML模板

add_form_template = None
change_form_template = None
change_list_template = None
delete_confirmation_template = None
delete_selected_confirmation_template = None
object_history_template = None

11. raw_id_fields,详细页面,针对FK和M2M字段变成以Input框形式

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin): raw_id_fields = ('FK字段', 'M2M字段',)

12.  fields,详细页面时,显示字段的字段

添加页面原始显示:
      

  修改了添加页面的显示字段:

class BookConfig(admin.ModelAdmin):
...
fields = ['user', ]

  修改后显示效果:

  

13. exclude,详细页面时,排除的字段

class BookConfig(admin.ModelAdmin):
...
# fields = ['user', ]
exclude = ['user', 'room']

  与fields相反,排除哪些字段不显示,显示效果如下:

  

14.  readonly_fields,详细页面时,只读字段

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
readonly_fields = ('user',)

15. fieldsets,详细页面时,使用fieldsets标签对数据进行分割显示

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
fieldsets = (
('基本数据', {
'fields': ('user', 'pwd', 'ctime',)
}),
('其他', {
'classes': ('collapse', 'wide', 'extrapretty'), # 'collapse','wide', 'extrapretty'
'fields': ('user', 'pwd'),
}),
)

16. 详细页面时,M2M显示时,数据移动选择(方向:上下和左右)

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
filter_vertical = ("m2m字段",) # 或filter_horizontal = ("m2m字段",)

17. ordering,列表时,数据排序规则

class BookConfig(admin.ModelAdmin):
list_display = ["id", "user", "room", "date"] # 不能放多对多字段
ordering = ["id"]

  添加“id”字段显示,并进行排序,显示如下:

  

  在添加的字段前加“-”,即是反向排序:

class BookConfig(admin.ModelAdmin):
ordering = ['-date'] # 反向排序

  ordering = []中可以添加多个字段,但不是联合排序,而是在第一个字段排序相同的情况下,按第二个字段排序。

class BookConfig(admin.ModelAdmin):
ordering = ['-date', "time_id"]

18.  radio_fields,详细页面时,使用radio显示选项(FK默认使用select)

radio_fields = {"ug": admin.VERTICAL} # 或admin.HORIZONTAL

19. form = ModelForm,用于定制用户请求时候表单验证

from app01 import models
from django.forms import ModelForm
from django.forms import fields class MyForm(ModelForm):
others = fields.CharField() class Meta:
model = models = models.UserInfo
fields = "__all__" @admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin): form = MyForm

20. empty_value_display = "列数据为空时,显示默认值"

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
empty_value_display = "列数据为空时,默认显示" list_display = ('user','pwd','up') def up(self,obj):
return obj.user
up.empty_value_display = "指定列数据为空时,默认显示"

二、单例模式

  单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

  比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。

  在 Python 中,我们可以用多种方法来实现单例模式:

  • 使用模块
  • 使用 __new__
  • 使用装饰器(decorator)
  • 使用元类(metaclass)

1、使用__new__

  为了使类只能出现一个实例,我们可以使用 __new__ 来控制实例的创建过程,代码如下:

class Singleton(object):
_instance = None def __new__(cls, *args, **kw):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kw)
return cls._instance class MyClass(Singleton):
a = 1 one = MyClass()
one.a = 3 two = MyClass()
print(two.a)
print("one", id(one))
print("tow", id(two))
"""
3
one 4362186704
tow 4362186704
"""

  在上面的代码中,我们将类的实例和一个类变量 _instance 关联起来,如果 cls._instance 为 None 则创建实例,否则直接返回 cls._instance

  通过执行情况可以看到,创建的两个实例内存地址相同,其实是一个对象。因此第一个对象修改a的值后,创建第二对象其实只是指向这个内存地址,a的值也是被修改过的。

2、使用模块

  其实,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。

(1)示例验证:

  mysingleton.py:

class My_Singleton(object):
x = 12 def foo(self):
print(self.x) my_singleton = My_Singleton()
print("OK")

  main.py:

from mysingleton import my_singleton

print(id(my_singleton))

from mysingleton import my_singleton

print(id(my_singleton))

"""
OK
4366742976
4366742976
"""

  注意这里的导入的不是类还是实例对象。

  这里只打印了一次“OK”,这是因为第一次导入模块的时,就已经将代码执行了一遍。加载过程中生成了一个.pyc中间文件。将执行中拿到变量放到.pyc文件中。再一次导入模块时,不再执行代码,而是直接去.pyc文件中存好的实例对象中拿取变量。

(2)示例验证2

mysingleton.py:

class My_Singleton(object):
x = 12 def foo(self):
print(self.x) my_singleton = My_Singleton() print("OK")

func.py:

from mysingleton import my_singleton

def foo():
print(id(my_singleton))

main.py:

from mysingleton import my_singleton

print(id(my_singleton))

from mysingleton import my_singleton

print(id(my_singleton))

from func import *

foo()

"""
OK
4362186536
4362186536
4362186536
"""

  一个程序不管导入的形式如何变换,还是从同一个.pyc文件中去取。

  程序跑起来后,导入一次后,只要还是程序过程中,其他地方的导入拿到的实例对象和之前那个实例对象是一个对象。

三、admin源码执行流程

1、循环加载执行所有已经注册的app中的admin.py文件

def autodiscover():
autodiscover_modules('admin', register_to=site)

2、执行代码

#admin.py

class BookAdmin(admin.ModelAdmin):
list_display = ("title",'publishDate', 'price') admin.site.register(Book, BookAdmin) admin.site.register(Publish)

3、admin.site

  这里应用的是一个单例模式,对于AdminSite类的一个单例模式,执行的每一个app中的每一个admin.site都是一个对象

4、执行register方法

admin.site.register(Book, BookAdmin)
admin.site.register(Publish)
class ModelAdmin(BaseModelAdmin):pass

def register(self, model_or_iterable, admin_class=None, **options):
if not admin_class:
admin_class = ModelAdmin
# Instantiate the admin class to save in the registry
self._registry[model] = admin_class(model, self)

  思考:在每一个app的admin .py中加上

print(admin.site._registry)   # 执行结果?

  在一个程序里,只要用到admin.site不管在几个app中都是一个对象。因此admin.site._registry执行结果都是得到所有的注册对象。

  到这里,注册结束!

5、admin的URL配置

urlpatterns = [
url(r'^admin/', admin.site.urls),
]
class AdminSite(object):

     def get_urls(self):
from django.conf.urls import url, include urlpatterns = [] # Add in each model's views, and create a list of valid URLS for the
# app_index
valid_app_labels = []
for model, model_admin in self._registry.items():
urlpatterns += [
url(r'^%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)),
]
if model._meta.app_label not in valid_app_labels:
valid_app_labels.append(model._meta.app_label) return urlpatterns @property
def urls(self):
return self.get_urls(), 'admin', self.name

6、url()方法的扩展应用

from django.shortcuts import HttpResponse
def test01(request):
return HttpResponse("test01") def test02(request):
return HttpResponse("test02") urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^yuan/', ([
url(r'^test01/', test01),
url(r'^test02/', test02), ],None,None)),
]

  运用url()方法分发的示例:

urlpatterns = [
path('admin/', admin.site.urls),
...
url(r"^yuan/", ([
url(r'^test01/', ([
url(r'^test04/', test04),
url(r'^test05/', test05),
], None, None)),
url(r'^test02/', test02),
url(r'^test03/', test03),
], None, None))
]

  扩展优化

from django.conf.urls import url,include
from django.contrib import admin from django.shortcuts import HttpResponse def change_list_view(request):
return HttpResponse("change_list_view")
def add_view(request):
return HttpResponse("add_view")
def delete_view(request):
return HttpResponse("delete_view")
def change_view(request):
return HttpResponse("change_view") def get_urls(): temp=[
url(r"^$".format(app_name,model_name),change_list_view),
url(r"^add/$".format(app_name,model_name),add_view),
url(r"^\d+/del/$".format(app_name,model_name),delete_view),
url(r"^\d+/change/$".format(app_name,model_name),change_view),
] return temp url_list=[] for model_class,obj in admin.site._registry.items(): model_name=model_class._meta.model_name
app_name=model_class._meta.app_label # temp=url(r"{0}/{1}/".format(app_name,model_name),(get_urls(),None,None))
temp=url(r"{0}/{1}/".format(app_name,model_name),include(get_urls()))
url_list.append(temp) urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^yuan/', (url_list,None,None)),
]

7、仿admin的url转发

"""MRBS URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from app01 import views
from django.conf.urls import url from django.shortcuts import HttpResponse def yuan(request):
return HttpResponse("Yuan") def test01(request):
return HttpResponse("test01") def test02(request):
return HttpResponse("test02") def test03(request):
return HttpResponse("test03") def test04(request):
return HttpResponse("test04") def test05(request):
return HttpResponse("test05") def add(request):
return HttpResponse("add") def delete(request, id):
return HttpResponse("delete") def change(request, id):
return HttpResponse("change") def list_view(request):
return HttpResponse("list_view") def get_urls2(): temp = []
temp.append(url(r"^add/",add))
temp.append(url(r"^(\d+)/delete/",delete))
temp.append(url(r"^(\d+)/change/",change))
temp.append(url(r"^$",list_view))
return temp def get_urls():
temp = []
print('_registry:', admin.site._registry) # 键值就是所有的注册表 for model, admin_class in admin.site._registry.items():
print("model", model)
print("admin_class", admin_class) # app01.BookConfig
"""
所有的注册模型表
model <class 'django.contrib.auth.models.Group'>
model <class 'app01.models.Book'>
model <class 'app01.models.UserInfo'>
model <class 'app01.models.Room'>
"""
# temp.append(path(r"app01/book", yuan))
# temp.append(path(r"%s/%s" % (app名称怎么取?, 模型名称怎么取?), yuan))
# 如何通过model类变量获取该模型的字符串名称和该模型所在的app的字符串名称?
# print("====>>", model._meta.model_name) # 模型名称 book/userinfo/room
# print("====>>", model._meta.app_label) # app名称 app01 model_name = model._meta.model_name
app_label = model._meta.app_label
temp.append(path(r"%s/%s/" % (app_label, model_name), (get_urls2(), None, None))) return temp urlpatterns = [
path('admin/', admin.site.urls),
path('login/', views.login),
path('index/', views.index),
path('book/', views.book), path('yuan/', (get_urls(), None, None)),
]

注意:

(1)admin.site单例对象,admin.site._registry拿到所有的注册对象,形式如下所示:

_registry: 
{<class 'django.contrib.auth.models.Group'>: <django.contrib.auth.admin.GroupAdmin object at 0x105d24f98>,
<class 'app01.models.Book'>: <app01.admin.BookConfig object at 0x105d6d470>,
<class 'app01.models.UserInfo'>: <django.contrib.admin.options.ModelAdmin object at 0x105d6d5c0>,
<class 'app01.models.Room'>: <django.contrib.admin.options.ModelAdmin object at 0x105d6d5f8>}

(2)循环遍历admin.site._registry, 拿到所有的注册模型表

def get_urls():
temp = []
print('_registry:', admin.site._registry) # 键值就是所有的注册表 for model, admin_class in admin.site._registry.items():
print("model", model)
# print("admin_class", admin_class) # app01.BookConfig
"""
所有的注册模型表
model <class 'django.contrib.auth.models.Group'>
model <class 'app01.models.Book'>
model <class 'app01.models.UserInfo'>
model <class 'app01.models.Room'>
"""

(3)通过model类变量获取该模型的字符串名称和该模型所在的app的字符串名称。

def get_urls():
temp = [] for model, admin_class in admin.site._registry.items(): # temp.append(path(r"app01/book", yuan))
# temp.append(path(r"%s/%s/" % (app名称怎么取?, 模型名称怎么取?), yuan))
# 如何通过model类变量获取该模型的字符串名称和该模型所在的app的字符串名称?
print("====>>", model._meta.model_name) # 模型名称 book/userinfo/room
print("====>>", model._meta.app_label) # app名称 app01

(4)根据拿到的模型名和app名称,拼接路径并添加到列表中。

  根据url多级分发规则:url(r"^yuan/"([url(r'^app01/book/',([url(r'12/delete/')],None,None)), ],None,None))

def get_urls2():
temp = []
temp.append(url(r"^add/",add))
temp.append(url(r"^(\d+)/delete/",delete))
temp.append(url(r"^(\d+)/change/",change))
temp.append(url(r"^$",list_view))
return temp def get_urls():
temp = []
for model, admin_class in admin.site._registry.items():
model_name = model._meta.model_name
app_label = model._meta.app_label
temp.append(path(r"%s/%s/" % (app_label, model_name), (get_urls2(), None, None))) return temp urlpatterns = [
path('admin/', admin.site.urls),
path('yuan/', (get_urls(), None, None)),
]

  显示效果:

  

Django——admin管理工具的更多相关文章

  1. Django admin 管理工具

    admin 组件的使用 Django 提供了基于 web 的管理工具.Django 自动管理工具是 django.contrib 的一部分. INSTALLED_APPS = [ 'django.co ...

  2. 吴裕雄--天生自然Django框架开发笔记:Django Admin 管理工具

    Django 提供了基于 web 的管理工具. Django 自动管理工具是 django.contrib 的一部分.可以在项目的 settings.py 中的 INSTALLED_APPS 看到它: ...

  3. 10.5Djang admin 管理工具

    2018-10-5 17:30:57 Django admin 管理工具  参考连接: https://www.cnblogs.com/yuanchenqi/articles/8323452.html ...

  4. Django 之 admin管理工具

    -------------------------------------------------------------------------妄尝恶果,苦果自来. admin组件使用 Django ...

  5. Django的 admin管理工具

    admin组件使用 Django 提供了基于 web 的管理工具. Django 自动管理工具是 django.contrib 的一部分.你可以在项目的 settings.py 中的 INSTALLE ...

  6. Django框架 之 admin管理工具(组件使用)

    Django框架 之 admin管理工具(组件使用) 浏览目录 激活管理工具 使用管理工具 admin的定制 admin组件使用 Django 提供了基于 web 的管理工具. Django 自动管理 ...

  7. 自定义admin管理工具(stark组件)

    自定义admin管理工具(stark组件) 创建项目 了解了admin的功能后,我们可以开始仿照admin编写我们自己的管理工具stark组件 首先创建一个新的项目,并创建三个app stark就是我 ...

  8. admin管理工具

    admin组件使用 Django 提供了基于 web 的管理工具. Django 自动管理工具是 django.contrib 的一部分.你可以在项目的 settings.py 中的 INSTALLE ...

  9. django之admin管理工具

    admin组件 admin是django提供的基于web的管理工具 >如何使用: 1.激活管理工具 通常会在生成项目时在urls.py中自动设置好 from django.urls import ...

随机推荐

  1. 更改Linux下的时间

    1.使用tzseletect glibc-common-2.12-1.192.el6.x86_64 : Common binaries and locale data for glibc Repo : ...

  2. WebGL学习之法线贴图

    实际效果请看demo:纹理贴图 为了增加额外细节,提升真实感,我们使用了漫反射贴图和高光贴图,它们都是向三角形进行附加纹理.但是从光的视角来看是表面法线向量使表面被视为平坦光滑的表面.以光照算法的视角 ...

  3. DQL、DML、DDL、DCL的区别

    1. 历史发展 SQL(Structure Query Language)语言是数据库的核心语言. SQL的发展是从1974年开始的,其发展过程如下:1974年-----由Boyce和Chamberl ...

  4. redis中使用lua脚本

    lua脚本 Lua是一个高效的轻量级脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能 使用脚本的好处 1.减少网络开销,在Lua脚 ...

  5. shim和polyfill,前端术语

    最近项目临近发布,JS的bug大都修改完毕,终于进入了我在这家公司实习+入职为数不多的摸鱼时刻.(想想真是有点感人啊) 因为项目要兼容IE8,所以我们的代码里常常要用到 shim 以支持ES5 的相关 ...

  6. Myeclipse经常弹出Subversion Native Library Not Available

  7. 115th LeetCode Weekly Contest Prison Cells After N Days

    There are 8 prison cells in a row, and each cell is either occupied or vacant. Each day, whether the ...

  8. KM算法(运用篇)

    传送门:KM算法---理解篇 最佳匹配 什么是完美匹配 如果一个二分图,X部和Y部的顶点数相等,若存在一个匹配包含X部与Y部的所有顶点,则称为完美匹配. 换句话说:若二分图X部的每一个顶点都与Y中的一 ...

  9. PIE SDK栅格增强控制

    1. 功能简介 亮度是指发光体(反光体)表面发光(反光)强弱的物理量:对比度指的是一幅图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量:透明度是描述光线透过的程度 栅格数据增强控制主要是通过对亮 ...

  10. 转 C#对多个集合和数组的操作(合并,去重,判断)

    在开发过程中.数组和集合的处理是最让我们担心.一般会用for or foreach 来处理一些操作.这里介绍一些常用的集合跟数组的操作函数. 首先举例2个集合A,B. List<int> ...