django-jet 中文文檔


關於
JET是新式的Django管理界面並且增強了功能。

 
 

內容

文檔

  • 開始
  • 安裝django-jet
  • 安裝儀表盤
  • 配置
  • 配置文件
  • 自動補全
  • 緊湊內聯
  • 過濾器
  • 儀表盤
  • 自定義儀表盤
  • 儀表盤模塊
  • 自定義儀表盤模塊
  • 儀表盤API
  • 儀表盤
  • 儀表盤模塊

 

許可
Django-JET使用開源(AGPLv3)和商業兩種性質的協議。請注意如果程序中使用AGPLv3協議的代碼那么您的代碼也應符合AGPL許可協議。如果您不想那么做我們可以提供一份商業性的許可協議(訪問主頁)。這份商業性的許可協議允許您將Django-JET應用於商業性的產品或應用中而不需符合AGPLv3許可。

資源
<ul>
<li>主頁:http://jet.geex-arts.com/
<li>在線Demo:http://demo.jet.geex-arts.com/admin/
<li>libi.io:http://libi.io/library/1683/django-jet
<li>PyPI:https://pypi.python.org/pypi/django-jet
<li>支持: support@jet.geex-arts.com
</ul>

截圖

 
**Index dashboard**
</li>
<li>
 
**Changelist**
</li>
<li>
 
Paste_Image.png
</li></ul>

 

安裝#

當你按照這個教程操作后Django JET儀表盤還不能啟動(因為它位於一個單獨的應用中)。如果您想使之工作,您需要按照安裝儀表盤的步驟啟用儀表盤。

<ul>
<li>下載最新版本的Django JET

pip install djang-jet
# or easy_install django-jet 

<li>將'jet'應用添加到你的Django項目的設置文件settings.py中的INSTALLED_APPS設置中(注意'jet'應位於'django.contrib.admin'之前)

INSTALLED_APPS = (
        ...
        'jet', 'django.contrib.admin', ... ) 

<li> 確認在settings.py中啟用了上下文處理器django.template.context_precessors.request(Djang 1.8以上版本)

在django 1.8之前應該使用不能的方式指定上下文處理器。即使用django.core.context_preocessor.request代替django.template.context_precessors.request

from django.conf import global_settings TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + ( 'django.core.context_processors.request', ) 

<li>在項目的urls.py文件的urlpatterns中添加url模版(為了關聯到相關路由)

urlpatterns = patterns(
    '', url(r'^jet/', include('jet.urls', 'jet')), # Django JET URLS url(r'^admin/', include(admin.site.urls)), ... ) 

<li> 創建數據表

python manage.py migrate jet # or python manage.py syncdb 

<li> 收集靜態文件(產品環境中)
python manage.py collectstatic
<li>清理瀏覽器緩存
</ul>

儀表盤安裝#

儀表盤位於一個單獨的應用中。所以當完成標准的JET安裝后它還不能工作。需要按照以下步驟啟用儀表盤應用:
<ul>
<li>將'jet.dashboard'應用添加到你的Django項目的設置文件settings.py中的INSTALLED_APPS設置中(注意'jet.dashboard'應位於'jet'之前)

INSTALLED_APPS = (
    ...
    'jet.dashboard', 'jet', 'django.contrib.admin', ... ) 

<li>在項目的urls.py文件的urlpatterns中添加url模版(為了關聯到相關路由)

urlpatterns = patterns(
    '', url(r'^jet/', include('jet.urls', 'jet')), # Django JET URLS url(r'^jet/dashboard/', include('jet.dashboard.urls', 'jet-dashboard')), # Django JET dashboard URLS url(r'^admin/', include(admin.site.urls)), ... ) 

<li>安裝python包For Google Analytics widgets only
pip install google-api-python-client==1.4.1
<li>創建數據表

python manage.py migrate dashboard # or python manage.py syncdb 

<li>收集靜態文件(產品環境中)
python manage.py collectstatic
</ul>
儀表盤已經安裝了。學習Dashboard章節以自定義儀表盤。

配置#

配置文件##

配置是指在settings.py中一些可用的選項:

JET_DEFAULT_THEME###

Django JET允許用戶改變默認的主題。這個特點主要是用來自定義顏色方案而不是制作一個完全不同的主題。這個選項實際上的作用是使Django加載不同的css文件。

可用的內置主題如下:
<ul>
<li>default(默認)
<li>green(綠色)
<li>light-violet(淺紫色)
<li>light-green(淺綠色)
<li>light-blue(淺藍)
<li>light-gray(淺灰)
</ul>
可以使用參數改變主題
JET_DEFAULT_THEME = 'light-gray'

JET_THEMES###

 
 

可以允許用戶自行改變管理面板的配色方案。這個選項會添加配色方案選擇器到用戶的下拉菜單。如果要禁用這個選項只需使JET_THEMS是一個空的list即可。

JET_THEMES = [
    {
        'theme': 'default', # theme folder name 'color': '#47bac1', # color of the theme's button in user menu 'title': 'Default' # theme title }, { 'theme': 'green', 'color': '#44b78b', 'title': 'Green' }, { 'theme': 'light-green', 'color': '#2faa60', 'title': 'Light Green' }, { 'theme': 'light-violet', 'color': '#a464c4', 'title': 'Light Violet' }, { 'theme': 'light-blue', 'color': '#5EADDE', 'title': 'Light Blue' }, { 'theme': 'light-gray', 'color': '#222', 'title': 'Light Gray' } ] 

自定義JET_THEME

可以通過在/static/jet/css/thems/下添加新的文件夾的方式自行添加配色方案。你可以使用/jet/static/jet/css/themes/light-violet/文件夾作為一個例子(在Django JET代碼中獲得)。_variables.scss中包含了所有可以自行以的變量。你需要編譯這個目錄下的所有.scss文件才能使用自己的主題。

菜單壓縮

 

 
Compact Or Not

如果您沒有很多的應用或者模塊卻顯示二級菜單可能會使您感到厭煩。關於這點您可以使用菜單的壓縮模式它會在側邊菜單欄直接顯示應用和模塊而不再需要移動鼠標到應用上而再展示相關的模塊。
JET_SIDE_MENU_COMPACT = True
這個選項默認為False。

 

自定義菜單

默認情況下JET將應用和它的模塊按照字母表的順序展示在側邊菜單欄。如果您想展示特定的應用和模塊或者改變他們的順序則可以使用JET_SIDE_MENU_CUSTOM_APPS來設置

JET_SIDE_MENU_CUSTOM_APPS = [
   ('core', [ # Each list element is a tuple with application name (app_label) and list of models 'User', 'MenuItem', 'Block', ]), ('shops', [ 'Shop', 'City', 'MetroStation', ]), ('feedback', [ 'Feedback', ]), ] 

如果您想展示某個應用的所有模塊,可以使用__all__關鍵字

JET_SIDE_MENU_CUSTOM_APPS = [
    ('core', ['__all__']), ... ] 

如果有多個管理站點並且想要給不同的站點指定不同的應用菜單,可以使用站點名稱作為字典的key,將菜單的列表作為value來設定。

可以使用jet _custom_apps_example這個管理命令來生成JET_SIDE_MENU_CUSTOM_APPS的示例。這個示例中會包括所有的應用和模塊。你可以這樣使用它:
python manage.py jet_custom_apps_example

JET_CHANGE_FORM_SIBLING_LINKS

 
Paste_Image.png

在頁面上添加前進或者后退的導航按鈕可以讓您在編輯完成后直接返回而不用先到變更列表。如果這個功能影響到了性能的話可以在設置中禁用。
JET_CHANGE_FORM_SIBLING_LINKS = True
默認情況下這個選項為True

JET_INDEX_DASHBOARD

設置管理主頁的儀表盤用到的類。這個特性可以使用戶建立自己的帶有自定義模塊和已經安裝的布局的儀表盤。
JET_INDEX_DASHBOARD = 'jet.dashboard.dashboard.DefaultIndexDashboard'

JET_APP_INDEX_DASHBOARD

和JET_INDEX_DASHBOARD的功能相同,但是作用的是應用的頁面。

JET_APP_INDEX_DASHBOARD = 'jet.dashboard.dashboard.DefaultAppIndexDashboard' 

自動補全

默認情況下Django JET會對輸入的查詢條件提供全部可能的選項。當存在大量的可用的選項時這個結果並不一定是您所想要的。為此,Django JET允許您使用AJAX動態的加載結果。

配置

為了達成這個功能您需要做以下的事情:
<ul>
<li>指定需要使用AJAX方式查詢的模塊字段。將下面這個將可以使用AJAX查詢的字段的字段名作為元組或列表返回的靜態方法加入的模塊中。

@staticmethod def autocomplete_search_fields(): return 'field1', 'field2' # for single field @staticmethod def autocomplete_search_fields(): return 'field1', 

一個示例:

class Address(models.Model): name = models.CharField(_('name'), max_length=255) city = models.ForeignKey(City, verbose_name=_('city'), related_name='addresses') zip = models.IntegerField(_('zip/postal code')) class Meta: verbose_name = _('address') verbose_name_plural = _('addresses') unique_together = ('name', 'city') def __str__(self): return self.name @staticmethod def autocomplete_search_fields(): return 'name', 'city__name' 

<li>如果有外鍵關聯的話可以使用自定義的AJAX篩選類jet.filters.RelatedFieldAjaxListFilter

from jet.filters import RelatedFieldAjaxListFilter class PersonAdmin(admin.ModelAdmin): list_filter = ( ... ('address', RelatedFieldAjaxListFilter), ) 

<li>現在管理界面所有的選擇框會使用AJAX的方式來查詢並展示可用的選項。
這些是為雙外鍵和多對多關系的字段所做的。
</ul>

為某些字段去除自動補全

自動補全在大多數情況下是適用的,但有時你希望限制給某個空間提供的數據條數。這種情況下你可以通過下面這種方式禁用自動補全:

class YourForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(YourForm, self).__init__(*args, **kwargs) if SOME_CASE(self.instance): self.fields['FIELD_NAME'].autocomplete = False self.fields['FIELD_NAME'].queryset = Model.queryset.some_filter() 

緊湊內聯

默認情況下Django管理界面提供了內聯方式以供用戶在同一頁面編輯相關聯的幾種模型-StackedInlineTabularInline。在沒有那么多對象時大部分使用的都是StackedInline的方式。如果相關聯的模型很多,TabularInline可以幫助到您,但是當相關聯的模型有很多字段的話並不方便關聯他們。為了解決這個問題JET內置了CompactInline類。

 
Paste_Image.png

用法

CompactInline的工作方式就像Django內置的內聯方式一樣。只需要繼承自jet.admin.CompactInline內聯類即可。

from django.contrib import admin from people.models import County, State, City from jet.admin import CompactInline class StateCountiesInline(admin.TabularInline): model = County extra = 1 show_change_link = True class StateCitiesInline(CompactInline): model = City extra = 1 show_change_link = True class StateAdmin(admin.ModelAdmin): inlines = (StateCountiesInline, StateCitiesInline) 

過濾器

RelatedFieldAjaxListFilter

參見Autocomplete文檔

django-admin-rangefilter

為了糾正django-admin-rangefilter包的兼容性問題,你需要使用JET的過濾器管理類jet.filter.DateRangeFilter來代替rangefilter.filter.DateRangeFilter

#from rangefilter.filter import DateRangeFilter from jet.filters import DateRangeFilter class MyUserAdmin(UserAdmin): ... list_filter = ( ('date_joined', DateRangeFilter), ) 

儀表盤

自定義儀表盤

Django JETDashboard盡可能的與django-admin -tools dashboard兼容以使django-admin-tools模塊移植到Django JET上。大多數情況下可以在模塊的模版中更改python的導入和移除之前的繼承。
Dashboard相當於Dashboard類的實例,DashboardModule是其的子類。所有的自定義Dashboard應當繼承jet.dashboard.dashboard.Dashboard並且使用init_with_context來填充控件。你應該將你的控件添加到childrenavailable_children屬性
進行下面的步驟之前要先確認您已安裝了Dashboard

開始自定義Dashboard

<ul>
<li>在合適的位置創建dashboard.py文件(例如項目的根目錄下),編輯一下內容

from django.utils.translation import ugettext_lazy as _ from jet.dashboard import modules from jet.dashboard.dashboard import Dashboard, AppIndexDashboard class CustomIndexDashboard(Dashboard): columns = 3 def init_with_context(self, context): self.available_children.append(modules.LinkList) self.children.append(modules.LinkList( _('Support'), children=[ { 'title': _('Django documentation'), 'url': 'http://docs.djangoproject.com/', 'external': True, }, { 'title': _('Django "django-users" mailing list'), 'url': 'http://groups.google.com/group/django-users', 'external': True, }, { 'title': _('Django irc channel'), 'url': 'irc://irc.freenode.net/django', 'external': True, }, ], column=0, order=0 )) 

<li>將settings.py文件的路徑添加到創建的dashboard.py文件中(假設dashboard.py在項目根目錄下)

JET_INDEX_DASHBOARD = 'dashboard.CustomIndexDashboard' 

現在您有了一個只有一個LinkList控件的dashboard。如果您有另外一個dashboard並且已經渲染完成的話您需要重啟dashboard。訪問Dashboard Modules學習其他可以應用於自定義dashboard的組件或者從Custom Dashboard Module建立自己的控件。

Dashboard Modules

內置的Dashboard Modules

LinkList

 
Paste_Image.png
class jet.dashboard.modules.LinkList(title=None, children=[], **kwargs) 

用法

from django.utils.translation import ugettext_lazy as _ from jet.dashboard import modules from jet.dashboard.dashboard import Dashboard, AppIndexDashboard class CustomIndexDashboard(Dashboard): columns = 3 def init_with_context(self, context): self.available_children.append(modules.LinkList) self.children.append(modules.LinkList( _('Support'), children=[ { 'title': _('Django documentation'), 'url': 'http://docs.djangoproject.com/', 'external': True, }, { 'title': _('Django "django-users" mailing list'), 'url': 'http://groups.google.com/group/django-users', 'external': True, }, { 'title': _('Django irc channel'), 'url': 'irc://irc.freenode.net/django', 'external': True, }, ], column=0, order=0 )) 

children = []

children的屬性包括鏈接,你可以把他作為參數傳到構造器中以制作你自己的原裝的鏈表。
children是一個字典的數組

[
     {
         'title': _('Django documentation'), 'url': 'http://docs.djangoproject.com/', 'external': True, }, ... ] 

layout = 'stacked'

指定控件的布局,允許值為stackedinline

AppList

 
Paste_Image.png

class jet.dashboard.modules.AppList(title=None, model=None, context=None, **kwargs)

展示應用和其包含的模塊以及鏈接。每個模塊有響應的“創建”和“更改”鏈接
例子:

from django.utils.translation import ugettext_lazy as _ from jet.dashboard import modules from jet.dashboard.dashboard import Dashboard, AppIndexDashboard class CustomIndexDashboard(Dashboard): columns = 3 def init_with_context(self, context): self.children.append(modules.AppList( _('Applications'), exclude=('auth.*',), column=0, order=0 )) 

exclude = None

指定不展示的模塊,exclude是一個形如app_label.model的字符串的數組。支持用*來代表所有模塊(auto.**)

models = None
同exclude

ModelList

 
Paste_Image.png

class jet.dashboard.modules.ModelList(title=None, model=None, context=None, **kwargs)

展示模塊以及鏈接。每個模塊有響應的“創建”和“更改”鏈接
例子:

from django.utils.translation import ugettext_lazy as _ from jet.dashboard import modules from jet.dashboard.dashboard import Dashboard, AppIndexDashboard class CustomIndexDashboard(Dashboard): columns = 3 def init_with_context(self, context): self.children.append(modules.ModelList( _('Models'), exclude=('auth.*',), column=0, order=0 )) 

exclude = None

指定不展示的木塊,同AppList的exclude

models = None

同上

RecentActions

 
Paste_Image.png

class jet.dashboard.modules.RecentActions(title=None, limit=10, **kwargs)

展示最近的管理操作,包含實體名,操作類型,操作人,日期
例子:

from django.utils.translation import ugettext_lazy as _ from jet.dashboard import modules from jet.dashboard.dashboard import Dashboard, AppIndexDashboard class CustomIndexDashboard(Dashboard): columns = 3 def init_with_context(self, context): self.children.append(modules.RecentActions( _('Recent Actions'), 10, column=0, order=0 )) 

exclude_list = None

不展示的模塊,同AppList的exclude

include_list = None

同上

limit = 10

展示條數

Feed

 
Paste_Image.png

class jet.dashboard.modules.Feed(title=None, feed_url=None, limit=None, **kwargs)

展示訂閱資訊以及以下信息:記錄標題,日期,到完整內容的鏈接
例子:

from django.utils.translation import ugettext_lazy as _ from jet.dashboard import modules from jet.dashboard.dashboard import Dashboard, AppIndexDashboard class CustomIndexDashboard(Dashboard): columns = 3 def init_with_context(self, context): self.children.append(modules.Feed( _('Latest Django News'), feed_url='http://www.djangoproject.com/rss/weblog/', limit=5, column=0, order=0 )) 

feed_url = None

訂閱資訊的url(用戶可自行修改)

limit = None

展示條數

Google Analytics Widgets

需要另外安裝Google Analytics控件

 
Paste_Image.png

安裝

<ul>
<li>安裝Python包
pip install google-api-python-client==1.4.1
<ul>指定到Google Analytics client_secrets.json的路徑(從Google獲得)

JET_MODULE_GOOGLE_ANALYTICS_CLIENT_SECRETS_FILE = os.path.join(PROJECT_DIR, 'client_secrets.json') 

<li>在urls.py文件的開頭導入包

from jet.dashboard.dashboard_modules import google_analytics_views 

</ul>
例子:

from django.utils.translation import ugettext_lazy as _ from jet.dashboard.dashboard import Dashboard, AppIndexDashboard from jet.dashboard.dashboard_modules import google_analytics class CustomIndexDashboard(Dashboard): columns = 3 def init_with_context(self, context): self.available_children.append(google_analytics.GoogleAnalyticsVisitorsTotals) self.available_children.append(google_analytics.GoogleAnalyticsVisitorsChart) self.available_children.append(google_analytics.GoogleAnalyticsPeriodVisitors) 

Yandex Metrika Widgets

Yandex Metrika Widgets需要額外安裝

 
Paste_Image.png

安裝

<ul>
<li>設置 Yandex Metrika的CLIENT_ID和CLIENT_SECRET(從 Yandex Metrika的網站獲得)

JET_MODULE_YANDEX_METRIKA_CLIENT_ID = 'YANDEX_METRIKA_CLIENT_ID' JET_MODULE_YANDEX_METRIKA_CLIENT_SECRET = 'YANDEX_METRIKA_CLIENT_SECRET' 

<li>在urls.py文件中導入包

from jet.dashboard.dashboard_modules import yandex_metrika_views 

例子

from django.utils.translation import ugettext_lazy as _ from jet.dashboard.dashboard import Dashboard, AppIndexDashboard from jet.dashboard.dashboard_modules import yandex_metrika class CustomIndexDashboard(Dashboard): columns = 3 def init_with_context(self, context): self.available_children.append(yandex_metrika.YandexMetrikaVisitorsTotals) self.available_children.append(yandex_metrika.YandexMetrikaVisitorsChart) self.available_children.append(yandex_metrika.YandexMetrikaPeriodVisitors) 

class jet.dashboard.dashboard_modules.yandex_metrika.YandexMetrikaVisitorsTotals(title=None, period=None, **kwargs)

Yandex Metrika 控件可以展示一段特定時期的訪問人數。時間區間可以是今天、上周、上月、上季度、上一年等。

period = None

展示的時間區間,允許值為表示天數的整數

class jet.dashboard.dashboard_modules.yandex_metrika.YandexMetrikaVisitorsChart(title=None, period=None, show=None, group=None, **kwargs)

展示特定時間區間的訪客/觀眾等人數的圖表。

group=None

設置數據的單位,可能的值為day/week/month

period=None

天數的整數值

show=None

展示的數據,可能值為visitors/visits/page_views

class jet.dashboard.dashboard_modules.yandex_metrika.YandexMetrikaPeriodVisitors(title=None, period=None, group=None, **kwargs)

和上一個差不多:)

自定義Dashboard Module

按照以下步驟來創建你自己的dashboard module
<ul>
<li>繼承Dashboard Module
<li>創建模塊模版
<li>(可選)添加模塊視圖
</ul>
當然您也可以參照代碼中在jet/dashboard/modules.py和jet/dashboard/dashboard_modules/位置內置的模塊。

繼承Dashboard Module

<ul>
<li>在你的django應用中創建dashboard modules文件dashboard_modules.py(或者其他名字)
<li>在創建的文件中創建dashboard modules類並繼承dashboard module類。從http://jet.readthedocs.io/en/latest/dashboard_api.html#dashboard-module查看可用的模塊屬性。init_with_context方法相當於控件的構造方法,可以用來加載數據和穿實話模塊的狀態。你可以將數據存儲到模塊的字段中並傳到模版中。
例子(dashboard_modules.py)

from jet.dashboard.modules import DashboardModule from contact.models import Ticket class RecentTickets(DashboardModule): title = 'Recent tickets' title_url = Ticket.get_admin_changelist_url() template = 'contact/dashboard_modules/recent_tickets.html' limit = 10 def init_with_context(self, context): self.children = Ticket.objects.order_by('-date_add')[:self.limit] 

<li>可選的,您可以在管理界面添加可自定義的設置和內容。為自定義設置的settings_form應設置,實現settings_dictload_settings方法。如要自定義內容的話應該設置child_form, child_namechild_name_plural,並且store_children方法應返回True。你可以從數據庫加載數據來驗證__init__方法。
</ul>

 
Paste_Image.png

 

自定義設置和可編輯的列表的例子:

class LinkList(DashboardModule): title = 'Links' template = 'jet.dashboard/modules/link_list.html' layout = 'stacked' children = [] settings_form = LinkListSettingsForm child_form = LinkListItemForm child_name = 'Link' child_name_plural = 'Links' def __init__(self, title=None, children=list(), **kwargs): children = list(map(self.parse_link, children)) kwargs.update({'children': children}) super(LinkList, self).__init__(title, **kwargs) def settings_dict(self): return { 'layout': self.layout } def load_settings(self, settings): self.layout = settings.get('layout', self.layout) def store_children(self): return True def parse_link(self, link): if isinstance(link, (tuple, list)): link_dict = {'title': link[0], 'url': link[1]} if len(link) >= 3: link_dict['external'] = link[2] return link_dict elif isinstance(link, (dict,)): return link class LinkListSettingsForm(forms.Form): layout = forms.ChoiceField(label='Layout', choices=(('stacked', 'Stacked'), ('inline', 'Inline'))) class LinkListItemForm(forms.Form): url = forms.CharField(label='URL') title = forms.CharField(label='Title') external = forms.BooleanField(label='External link', required=False) 

創建模塊模版

在模塊類中指定的位置創建模版。模塊的實例將傳到這個模版中並被命名為module以便從其中獲得數據

{% load humanize %}

<ul> {% for ticket in module.children %} <li> <span class="float-right"> <span class="dim"> {{ ticket.date_add|naturalday }} <span class="icon-clock tooltip" title="{{ ticket.date_add }}"></span> </span> </span> {% if ticket.forwarded %} <span class="icon-tick" style="color: #8ecb8e;"></span> {% else %} <span class="icon-cross" style="color: #dba4a4;"></span> {% endif %} <a href="{{ ticket.get_admin_url }}">{{ ticket.name }}</a> </li> {% empty %} <li> Nothing to show </li> {% endfor %} </ul> 

添加模塊視圖(可選)

如果您的dashboard modules需要有自己的屬兔您可以將他們按照下面的方法注冊並且存儲到文件中(如dashboard_modules_view.py)。

from django.conf.urls import url from django.contrib import messages from django.shortcuts import redirect from jet.dashboard import dashboard from core.utils.utils import DatabaseManager def update_database(request): database_manager = DatabaseManager() database_manager.update_database() messages.success(request, 'Database was successfully updated') return redirect(request.META.get('HTTP_REFERER')) # This method registers view's url dashboard.urls.register_urls([ url( r'^update_database/', update_database, name='update-database' ), ]) 

您應該在dashboard urls導入到主urls.py文件中之前導入這個文件

from django.conf import settings from django.conf.urls import include, url from django.contrib import admin # Import dashboard module views from core import dashboard_modules_views urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'^jet/', include('jet.urls', 'jet')), url(r'^jet/dashboard/', include('jet.dashboard.urls', 'jet-dashboard')), ... ] 

之后你可以按照下面的方法reverse url
{% url "jet-dashboard:update-database" %}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM