項目是有django django-rest-framework django-filter 組合。其中django-rest-framwork的幾個組合包一定要記得下載,否則會導致部分功能不能用。
這是依賴包,都得裝上。
- coreapi(1.32.0+) - 文檔生成支持。在django-filter的參數添加後可以直接在這裏顯示
- Markdown(2.1.0+) - Markdown對可瀏覽API的支持。(這個對於調試api特別方便)
- django-filter(1.0.1+) - 過濾支持。
- django-crispy-forms - 改進的HTML顯示以進行過濾。
- django-guardian(1.1.1+) - 對象級權限支持。
model.py:
class ClusterDevice(models.Model):
cluster = models.CharField(max_length=255, null=True, blank=True, verbose_name="集羣名稱")
comment = models.CharField(max_length=255, null=True, blank=True, verbose_name="詳情")
createtime = models.DateTimeField(auto_now_add=True, verbose_name="創建時間")
class Meta:
managed = False
db_table = 'cluster_device'
verbose_name = "設備集羣"
verbose_name_plural = verbose_name
def __str__(self):
return self.cluster
class Owner(models.Model):
owner_name = models.CharField(max_length=255, verbose_name="名稱")
mobile = models.IntegerField(verbose_name="手機號碼")
email = models.EmailField(max_length=255, blank=True, null=True, verbose_name="郵箱")
class Meta:
managed = False
db_table = "owner"
verbose_name = "聯繫人"
verbose_name_plural = verbose_name
def __str__(self):
return self.owner_name
class Device(models.Model):
CHOICE = (
(0, "失效"),
(1, "有效")
)
name = models.CharField(max_length=255, blank=True, null=True, verbose_name="設備名稱", unique=True)
status = models.IntegerField(choices=CHOICE, default=1, verbose_name="狀態")
type = models.ForeignKey(to=DeviceTag, related_name='tag_result', verbose_name="類型")
#注意此處的兩個外鍵
owner = models.ForeignKey(to=Owner, related_name='result', verbose_name="所有者")
password = models.CharField(max_length=255, blank=True, null=True, verbose_name="密碼")
class Meta:
managed = False
db_table = 'device'
verbose_name = "設備信息"
verbose_name_plural = verbose_name
def __str__(self):
return self.alias
序列化器:
class DeviceTagSerializer(serializers.ModelSerializer):
class Meta:
model = DeviceTag
fields = "__all__"
class ClusterDeviceSerializer(serializers.ModelSerializer):
class Meta:
model = ClusterDevice
fields = "__all__"
class OwnerSerializer(serializers.ModelSerializer):
class Meta:
model = Owner
fields = "__all__"
class DeviceSerializer(serializers.ModelSerializer):
# 此處的模式是:
# Device_model的字段=serializer.CharField(source='Device_model的字段.外鍵模型自定字段')
type = serializers.CharField(source='type.tag_name')
cluster_device = serializers.CharField(source='cluster_device.cluster')
owner = serializers.CharField(source='owner.owner_name')
class Meta:
model = Device
fields = "__all__"
假如不做自定義的序列化,那麼取到的數據將會是id,顯示很不友好。假如下面使用這樣的外鍵序列化
type = DeviceTagSerializer(many=True)
這樣返回的將會是外鍵的所有信息,那個外鍵表的所有字段,所有信息(或者是自定義的幾個字段)
而我們顯示要是外鍵的某個字段:那就必須序列化外鍵表的某個字段
type = serializers.CharField(source='type.tag_name')
序列化外鍵的使用方式就是上面那樣,自定義序列化一下,就好了。
注意: 自定義的序列化的格式,前面變量最好是model裏面的外鍵字段(此處也可以是type_name,但是這樣顯示的時候會多一個自斷,並且顯示還是id),後面的source中也必須是model中的字段,否則會報錯。不可迭代類型啊,xxmodel沒有xx屬性。
views:
class Pagination(PageNumberPagination):
'''
翻頁器
'''
page_size = 10
page_size_query_param = 'page_size'
#此處的也會自動在路由那也就是core的文檔中生成
page_query_param = "page"
max_page_size = 100
class DeviceListViews(mixins.ListModelMixin, viewsets.GenericViewSet):
'''
設備表
'''
queryset = DeviceController().get_all_device()
serializer_class = DeviceSerializer
pagination_class = Pagination
filter_backends = (DjangoFilterBackend,filters.SearchFilter)
filter_class = DeviceFilter
# print(queryset)
search_fields = ('id', 'alias', 'inner_ip', 'outer_ip', 'owner')
url:沒有使用register進行註冊的方式。
urlpatterns = [
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^docs/', include_docs_urls(title="基礎服務文檔"))
url(r'^DeviceList', DeviceListViews.as_view({'get': 'list'}), name='device'),
url(r'^OwnerList', OwnerListViews.as_view({'get': 'list'}), name='owner'),
# 這樣的url後會直接生成 /device/DeviceList?fields=xx使用
# drf+django-filter 的好處,就省下來好多的路由麻煩
]
filter文件:
class DeviceFilter(django_filters.rest_framework.FilterSet):
alias = django_filters.CharFilter(help_text="別名")
# 後面的help文字會在core文檔裏面生成
inner_ip = django_filters.CharFilter(help_text="內網ip")
outer_ip = django_filters.CharFilter(help_text="外網ip")
owner = django_filters.NumberFilter(help_text="所屬者的id")
class Meta:
model = Device
fields = ['id', 'alias', 'inner_ip', 'outer_ip', 'owner']
上面的djagno-filter+core+markdown效果:我的路由是使用的分發的狀態