models.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. from ckeditor_uploader.fields import RichTextUploadingField
  2. from django.contrib.sites.models import Site
  3. from django.db import models as m
  4. from django.db.models.signals import post_save, post_delete
  5. from django.dispatch import receiver
  6. from django.urls import reverse
  7. from django.utils.functional import cached_property
  8. from django.utils.timezone import now
  9. from blog.models import BaseModel
  10. from home import baidu
  11. from mdeditor.fields import MDTextField
  12. from website.utils import cache_decorator
  13. # Create your models here.
  14. #
  15. class HomeBaseModel(m.Model):
  16. created_time = m.DateTimeField('创建时间', default=now, editable=False)
  17. last_mod_time = m.DateTimeField('修改时间', default=now, editable=False)
  18. is_enable = m.BooleanField('是否启用', default=True)
  19. sequence = m.IntegerField('排列顺序', unique=True, null=True, blank=True)
  20. class Meta:
  21. abstract = True
  22. def save(self, *args, **kwargs):
  23. from website.blog_signals import article_save_signal
  24. # if not self.slug or self.slug == 'no-slug' or not self.id:
  25. # slug = self.title if 'title' in self.__dict__ else self.name
  26. # self.slug = slugify(slug)
  27. super().save(*args, **kwargs)
  28. # type = self.__class__.__name__
  29. is_update_views = 'update_fields' in kwargs and len(kwargs['update_fields']) == 1 and kwargs['update_fields'][
  30. 0] == 'views'
  31. article_save_signal.send(sender=self.__class__, is_update_views=is_update_views, id=self.id)
  32. def get_full_url(self):
  33. site = Site.objects.get_current().domain
  34. url = "http://{site}{path}".format(site=site, path=self.get_absolute_url())
  35. return url
  36. # 主页
  37. class Home(m.Model):
  38. slogan = RichTextUploadingField(max_length=100, verbose_name='口号')
  39. carousel_delay = m.IntegerField(verbose_name='跑马灯大图切换时间')
  40. testimonials_delay = m.IntegerField(verbose_name='客户评价切换时间')
  41. def __str__(self):
  42. return '主页'
  43. class Meta:
  44. verbose_name = '主页'
  45. verbose_name_plural = verbose_name
  46. def get_full_url(self):
  47. site = Site.objects.get_current().domain
  48. url = "http://{site}{path}".format(site=site, path=self.get_absolute_url())
  49. return url
  50. def get_absolute_url(self):
  51. return reverse('home:index')
  52. # 主页-跑马灯大图
  53. class HomeCarousel(HomeBaseModel):
  54. title = m.CharField(max_length=50, verbose_name='标题', blank=False)
  55. description = RichTextUploadingField(max_length=300, config_name='mini', verbose_name='描述', blank=False)
  56. image = m.ImageField(upload_to='upload/home/carousel/image', verbose_name='图片', blank=False)
  57. video = m.FileField(upload_to='upload/home/carousel/video', verbose_name='视频', blank=True)
  58. home = m.ForeignKey(Home, on_delete=m.CASCADE, verbose_name='主页')
  59. class Meta:
  60. verbose_name = '主页跑马灯'
  61. verbose_name_plural = verbose_name
  62. # 主页-我们的优势
  63. class HomeSuperiority(HomeBaseModel):
  64. title = m.CharField(max_length=50, verbose_name='标题', blank=False)
  65. description = RichTextUploadingField(max_length=300, blank=False, config_name='mini', verbose_name='描述')
  66. home = m.ForeignKey(Home, on_delete=m.CASCADE, verbose_name='主页')
  67. class Meta:
  68. verbose_name = '主页我们的优势'
  69. verbose_name_plural = verbose_name
  70. # 服务
  71. class Service(HomeBaseModel):
  72. name = m.CharField(max_length=50, verbose_name='服务名称')
  73. description = m.CharField(max_length=200, verbose_name='服务简介')
  74. thumb = m.ImageField(verbose_name='缩略图')
  75. slogan = m.CharField(max_length=100, verbose_name='服务口号')
  76. content = MDTextField(max_length=1000, null=True, verbose_name='服务详情')
  77. def __str__(self):
  78. return self.name
  79. class Meta:
  80. verbose_name = '服务'
  81. verbose_name_plural = verbose_name
  82. # 服务-内容
  83. class ServiceItem(HomeBaseModel):
  84. name = m.CharField(max_length=50, verbose_name='服务内容')
  85. description = RichTextUploadingField(max_length=200, config_name='mini', verbose_name='服务简介')
  86. service = m.ForeignKey(Service, on_delete=m.CASCADE, null=True, verbose_name='服务')
  87. class Meta:
  88. verbose_name = '服务内容'
  89. verbose_name_plural = verbose_name
  90. # 服务-流程和特点
  91. class ServerProcess(HomeBaseModel):
  92. name = m.CharField(max_length=50, verbose_name='服务流程')
  93. description = RichTextUploadingField(max_length=200, config_name='mini', verbose_name='服务流程简介')
  94. service = m.ForeignKey(Service, on_delete=m.CASCADE, null=True, verbose_name='服务')
  95. class Meta:
  96. verbose_name = '服务流程和特点'
  97. verbose_name_plural = verbose_name
  98. # 项目
  99. class Project(HomeBaseModel):
  100. name = m.CharField(max_length=50, verbose_name='项目名称')
  101. description = RichTextUploadingField(max_length=200, config_name='mini', verbose_name='项目简介')
  102. thumb = m.ImageField(upload_to="upload/project/thumb/%Y/%m/%d", verbose_name='缩略图')
  103. content = MDTextField(max_length=10000, verbose_name='项目详情')
  104. source_url = m.URLField(verbose_name='源码地址', null=True, blank=True)
  105. cycle = RichTextUploadingField(config_name='mini', verbose_name='项目周期', null=True, blank=True)
  106. service = m.ForeignKey(Service, on_delete=m.DO_NOTHING, null=True, blank=True, verbose_name='服务')
  107. tags = m.ManyToManyField('ProjectTag', verbose_name='技术标签')
  108. sequence = m.IntegerField('排列顺序', unique=True, null=False, blank=False)
  109. begin_time = m.DateTimeField('开始时间', default=now, editable=True)
  110. end_time = m.DateTimeField('结束时间', default=now, editable=True)
  111. related_projects = m.ManyToManyField('self', verbose_name="类似项目", blank=True, null=True,)
  112. # related_projects = m.ManyToManyField('self', to="", related_name=None, related_query_name=None,
  113. # limit_choices_to=None, symmetrical=None, through=None,
  114. # through_fields=None, db_constraint=True, db_table=None,
  115. # swappable=True, **kwargs)
  116. def __str__(self):
  117. return self.name
  118. class Meta:
  119. verbose_name = '项目'
  120. verbose_name_plural = verbose_name
  121. def get_absolute_url(self):
  122. return reverse('home:project-detail', kwargs={'pk': self.id})
  123. @cached_property
  124. def next_project(self):
  125. # 下一篇
  126. return Project.objects.filter(sequence__gt=self.sequence, is_enable=True).order_by('sequence').first()
  127. @cached_property
  128. def prev_project(self):
  129. # 前一篇
  130. return Project.objects.filter(sequence__lt=self.sequence, is_enable=True).order_by('-sequence').first()
  131. @cache_decorator(60 * 60 * 10)
  132. def get_related_projects(self):
  133. return Project.objects.all().filter(related_projects=self)
  134. # 项目-技术标签
  135. class ProjectTag(HomeBaseModel):
  136. name = m.CharField(max_length=50, verbose_name='技术标签名称')
  137. description = RichTextUploadingField(max_length=200, config_name='mini', blank=True, verbose_name='特点简介')
  138. def __str__(self):
  139. return self.name
  140. class Meta:
  141. verbose_name = '项目技术标签'
  142. verbose_name_plural = verbose_name
  143. # 项目-附件
  144. class ProjectAttach(HomeBaseModel):
  145. file = m.FileField(upload_to="upload/project/thumb/%Y/%m/%d", null=True, verbose_name='附件')
  146. name = m.CharField(max_length=50, null=True, verbose_name='附件名称', default=file.name)
  147. project = m.ForeignKey(Project, on_delete=m.CASCADE, null=True, verbose_name='项目')
  148. class Meta:
  149. verbose_name = '项目附件'
  150. verbose_name_plural = verbose_name
  151. # 关于
  152. class About(m.Model):
  153. introduce = RichTextUploadingField(max_length=800, config_name='full', verbose_name='介绍')
  154. address = m.CharField(max_length=100, verbose_name='地址')
  155. phone = m.CharField(max_length=20, verbose_name='电话')
  156. email = m.EmailField(verbose_name='邮箱')
  157. qq = m.CharField(max_length=20, verbose_name='QQ号')
  158. wechat = m.CharField(max_length=20, verbose_name='微信号')
  159. web_home = m.URLField(verbose_name='个人主页')
  160. github = m.URLField(verbose_name='GitHub主页')
  161. git_oschina = m.URLField(verbose_name='OsChina主页')
  162. def __str__(self):
  163. return self.web_home
  164. class Meta:
  165. verbose_name = '关于信息'
  166. verbose_name_plural = verbose_name
  167. # 关于-客户评价
  168. class Testimonials(HomeBaseModel):
  169. content = RichTextUploadingField(max_length=200, config_name='mini', verbose_name='评价内容')
  170. # author = m.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='作者', on_delete=m.DO_NOTHING)
  171. author = m.CharField(max_length=20, verbose_name='评价人')
  172. about = m.ForeignKey(About, on_delete=m.CASCADE, verbose_name='关于')
  173. class Meta:
  174. verbose_name = '客户评价'
  175. verbose_name_plural = verbose_name
  176. # 关于-我们的客户
  177. class OurClient(HomeBaseModel):
  178. logo = m.FileField(upload_to="upload/our_clients/", verbose_name='客户LOGO')
  179. url = m.URLField(verbose_name='客户官网地址')
  180. about = m.ForeignKey(About, on_delete=m.CASCADE, verbose_name='关于')
  181. class Meta:
  182. verbose_name = '我们的客户'
  183. verbose_name_plural = verbose_name
  184. # 关于-团队
  185. class TeamMember(HomeBaseModel):
  186. picture = m.ImageField(upload_to='upload/team/%Y/%m/%d', verbose_name='照片')
  187. name = m.CharField(max_length=20, verbose_name='姓名')
  188. job = m.CharField(max_length=50, verbose_name='职位')
  189. introduce = RichTextUploadingField(max_length=500, config_name='mini', verbose_name='介绍')
  190. about = m.ForeignKey(About, on_delete=m.CASCADE, verbose_name='关于')
  191. class Meta:
  192. verbose_name = '我们的团队'
  193. verbose_name_plural = verbose_name
  194. #
  195. # @receiver([post_save], sender=Project)
  196. # @receiver([post_save], sender=Home)
  197. # def save_handler(sender, instance, created, **kwargs):
  198. # url = instance.get_full_url()
  199. # bd_type = baidu.EnumBaiDu.create if created else baidu.EnumBaiDu.update
  200. # baidu.push_url2baidu(url, bd_type)
  201. #
  202. #
  203. # @receiver([post_delete], sender=Project)
  204. # @receiver([post_delete], sender=Home)
  205. # def delete_handler(sender, instance, **kwargs):
  206. # url = instance.get_full_url()
  207. # baidu.push_url2baidu(url, baidu.EnumBaiDu.delete)