From a2d714d85fffb500637aa6e9e4c52978acb9300b Mon Sep 17 00:00:00 2001 From: barney <15270405776@163.com> Date: Sat, 24 Sep 2022 00:33:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=BE=E7=89=87=E4=B8=8A=E4=BC=A0,=E8=AF=84?= =?UTF-8?q?=E8=AE=BA=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0006_avatar_article_avatar.py | 26 ++++++++ .../migrations/0007_alter_article_avatar.py | 19 ++++++ article/models.py | 14 +++++ article/permissions.py | 4 ++ article/serializers.py | 56 ++++++++++++++++-- article/views.py | 13 +++- comment/__init__.py | 0 comment/admin.py | 3 + comment/apps.py | 6 ++ comment/migrations/0001_initial.py | 32 ++++++++++ comment/migrations/__init__.py | 0 comment/models.py | 30 ++++++++++ comment/permissions.py | 26 ++++++++ comment/serializers.py | 15 +++++ comment/tests.py | 3 + comment/views.py | 14 +++++ db.sqlite3 | Bin 176128 -> 192512 bytes drf_vue_blog/settings.py | 10 +++- drf_vue_blog/urls.py | 10 +++- media/avatar/20220923/apple_00.png | Bin 0 -> 1006 bytes media/avatar/20220923/apple_01.png | Bin 0 -> 1642 bytes media/avatar/20220923/apple_02.png | Bin 0 -> 2092 bytes media/avatar/20220923/apple_03.png | Bin 0 -> 1553 bytes media/avatar/20220923/apple_04.png | Bin 0 -> 943 bytes media/avatar/20220923/apple_05.png | Bin 0 -> 1619 bytes media/avatar/20220923/apple_06.png | Bin 0 -> 1314 bytes media/avatar/20220923/apple_07.png | Bin 0 -> 1828 bytes media/avatar/20220923/apple_08.png | Bin 0 -> 1420 bytes media/avatar/20220923/apple_09.png | Bin 0 -> 1865 bytes media/avatar/20220923/apple_10.png | Bin 0 -> 1553 bytes media/avatar/20220923/apple_20.png | Bin 0 -> 1241 bytes 31 files changed, 269 insertions(+), 12 deletions(-) create mode 100644 article/migrations/0006_avatar_article_avatar.py create mode 100644 article/migrations/0007_alter_article_avatar.py create mode 100644 comment/__init__.py create mode 100644 comment/admin.py create mode 100644 comment/apps.py create mode 100644 comment/migrations/0001_initial.py create mode 100644 comment/migrations/__init__.py create mode 100644 comment/models.py create mode 100644 comment/permissions.py create mode 100644 comment/serializers.py create mode 100644 comment/tests.py create mode 100644 comment/views.py create mode 100644 media/avatar/20220923/apple_00.png create mode 100644 media/avatar/20220923/apple_01.png create mode 100644 media/avatar/20220923/apple_02.png create mode 100644 media/avatar/20220923/apple_03.png create mode 100644 media/avatar/20220923/apple_04.png create mode 100644 media/avatar/20220923/apple_05.png create mode 100644 media/avatar/20220923/apple_06.png create mode 100644 media/avatar/20220923/apple_07.png create mode 100644 media/avatar/20220923/apple_08.png create mode 100644 media/avatar/20220923/apple_09.png create mode 100644 media/avatar/20220923/apple_10.png create mode 100644 media/avatar/20220923/apple_20.png diff --git a/article/migrations/0006_avatar_article_avatar.py b/article/migrations/0006_avatar_article_avatar.py new file mode 100644 index 0000000..92154f3 --- /dev/null +++ b/article/migrations/0006_avatar_article_avatar.py @@ -0,0 +1,26 @@ +# Generated by Django 4.1.1 on 2022-09-23 22:51 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('article', '0005_rename_tag_article_tags'), + ] + + operations = [ + migrations.CreateModel( + name='Avatar', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content', models.ImageField(upload_to='avatar/%Y%m%d')), + ], + ), + migrations.AddField( + model_name='article', + name='avatar', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='articles', to='article.avatar'), + ), + ] diff --git a/article/migrations/0007_alter_article_avatar.py b/article/migrations/0007_alter_article_avatar.py new file mode 100644 index 0000000..aac4e71 --- /dev/null +++ b/article/migrations/0007_alter_article_avatar.py @@ -0,0 +1,19 @@ +# Generated by Django 4.1.1 on 2022-09-23 23:57 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('article', '0006_avatar_article_avatar'), + ] + + operations = [ + migrations.AlterField( + model_name='article', + name='avatar', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='article', to='article.avatar'), + ), + ] diff --git a/article/models.py b/article/models.py index 7cc78d4..0e4e054 100644 --- a/article/models.py +++ b/article/models.py @@ -28,6 +28,11 @@ class Tag(models.Model): return self.text +class Avatar(models.Model): + """标题图""" + content = models.ImageField(upload_to='avatar/%Y%m%d') + + # 博客文章 model class Article(models.Model): class Meta: @@ -59,6 +64,15 @@ class Article(models.Model): related_name='articles', ) + # 标题图 + avatar = models.ForeignKey( + Avatar, + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name='article' # 这里是1对1关系 + ) + # 标题 title = models.CharField(max_length=100) # 正文 diff --git a/article/permissions.py b/article/permissions.py index c64cf88..4e52cb9 100644 --- a/article/permissions.py +++ b/article/permissions.py @@ -1,4 +1,5 @@ from rest_framework import permissions +from rest_framework.permissions import BasePermission, SAFE_METHODS class IsAdminUserOrReadOnly(permissions.BasePermission): @@ -14,3 +15,6 @@ class IsAdminUserOrReadOnly(permissions.BasePermission): # 仅管理员可进行其他操作 return request.user.is_superuser + + + diff --git a/article/serializers.py b/article/serializers.py index 26d33cb..df3fbcd 100644 --- a/article/serializers.py +++ b/article/serializers.py @@ -1,7 +1,7 @@ from rest_framework import serializers -from article.models import Article, Category, Tag +from article.models import Article, Category, Tag, Avatar from user_info.serializers import UserDescSerializer - +from comment.serializers import CommentSerializer class CategorySerializer(serializers.ModelSerializer): """所有分类的序列化器""" @@ -16,6 +16,14 @@ class CategorySerializer(serializers.ModelSerializer): read_only_fields = ['created'] +class AvatarSerializer(serializers.ModelSerializer): + url = serializers.HyperlinkedIdentityField(view_name='avatar-detail') + + class Meta: + model = Avatar + fields = '__all__' + + class ArticleBaseSerializer(serializers.HyperlinkedModelSerializer): """将原来的ArticleSerializer抽象出一个父类""" author = UserDescSerializer(read_only=True) @@ -32,10 +40,45 @@ class ArticleBaseSerializer(serializers.HyperlinkedModelSerializer): slug_field='text', ) + # 图片字段 + avatar = AvatarSerializer(read_only=True) + avatar_id = serializers.IntegerField( + write_only=True, + allow_null=True, + required=False, + ) + + # 自定义错误信息 + default_error_messages = { + 'incorrect_avatar_id': 'Avatar with id {value} not exists.', + 'incorrect_category_id': 'Category with id {value} not exists.', + 'default': 'No more message here..' + } + + def check_obj_exists_or_fail(self, model, value, message='default'): + if not self.default_error_messages.get(message, None): + message = 'default' + # 不为None但是不存在该id返回错误信息 + if not model.objects.filter(id=value).exists() and value is not None: + # 若不存在则调用钩子方法fail()引发错误 + self.fail(message, value=value) + + # 验证图片id是否正确 + def validate_avatar_id(self, value): + self.check_obj_exists_or_fail( + model=Avatar, + value=value, + message='incorrect_avatar_id' + ) + return value + # 验证category_id是否正确 def validate_category_id(self, value): - if not Category.objects.filter(id=value).exists() and value is not None: - raise serializers.ValidationError("Category with id {} not exist.".format(value)) + self.check_obj_exists_or_fail( + model=Category, + value=value, + message='incorrect_category_id' + ) return value def to_internal_value(self, data): @@ -58,6 +101,8 @@ class ArticleSerializer(ArticleBaseSerializer): class ArticleDetailSerializer(ArticleBaseSerializer): + id = serializers.IntegerField(read_only=True) + comments = CommentSerializer(many=True, read_only=True) # 渲染后的正文 body_html = serializers.SerializerMethodField() # 渲染后的目录 @@ -102,10 +147,10 @@ class CategoryDetailSerializer(serializers.ModelSerializer): class TagSerializer(serializers.ModelSerializer): + """所有标签序列化器""" # 显示url # url = serializers.HyperlinkedIdentityField(view_name='tag-detail') - """所有标签序列化器""" class Meta: model = Tag @@ -126,3 +171,4 @@ class TagSerializer(serializers.ModelSerializer): return super(TagSerializer, self).update(instance, validated_data) + diff --git a/article/views.py b/article/views.py index f8d9faf..91387a9 100644 --- a/article/views.py +++ b/article/views.py @@ -1,7 +1,7 @@ from rest_framework import viewsets from article.serializers import ArticleSerializer, CategorySerializer, CategoryDetailSerializer -from article.serializers import TagSerializer,ArticleDetailSerializer -from article.models import Article, Category, Tag +from article.serializers import TagSerializer,ArticleDetailSerializer, AvatarSerializer +from article.models import Article, Category, Tag , Avatar from article.permissions import IsAdminUserOrReadOnly from rest_framework.filters import SearchFilter @@ -47,4 +47,11 @@ class TagViewSet(viewsets.ModelViewSet): """标签视图集""" queryset = Tag.objects.all() serializer_class = TagSerializer - permission_classes = [IsAdminUserOrReadOnly] \ No newline at end of file + permission_classes = [IsAdminUserOrReadOnly] + + +class AvatarViewSet(viewsets.ModelViewSet): + """标题图片视图集""" + queryset = Avatar.objects.all() + serializer_class = AvatarSerializer + permission_classes = [IsAdminUserOrReadOnly] diff --git a/comment/__init__.py b/comment/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/comment/admin.py b/comment/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/comment/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/comment/apps.py b/comment/apps.py new file mode 100644 index 0000000..c364f39 --- /dev/null +++ b/comment/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class CommentConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'comment' diff --git a/comment/migrations/0001_initial.py b/comment/migrations/0001_initial.py new file mode 100644 index 0000000..703dd26 --- /dev/null +++ b/comment/migrations/0001_initial.py @@ -0,0 +1,32 @@ +# Generated by Django 4.1.1 on 2022-09-23 23:57 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('article', '0007_alter_article_avatar'), + ] + + operations = [ + migrations.CreateModel( + name='Comment', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content', models.TextField()), + ('created', models.DateTimeField(default=django.utils.timezone.now)), + ('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='article.article')), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ['-created'], + }, + ), + ] diff --git a/comment/migrations/__init__.py b/comment/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/comment/models.py b/comment/models.py new file mode 100644 index 0000000..8d1d5c5 --- /dev/null +++ b/comment/models.py @@ -0,0 +1,30 @@ +from django.db import models +from django.utils import timezone +from article.models import Article +from django.contrib.auth.models import User + + +class Comment(models.Model): + # 评论人 + author = models.ForeignKey( + User, + on_delete=models.CASCADE, + related_name='comments', + ) + # 文章 + article = models.ForeignKey( + Article, + on_delete=models.CASCADE, + related_name='comments', + ) + # 评论内容 + content = models.TextField() + # 评论时间 + created = models.DateTimeField(default=timezone.now) + + class Meta: + ordering = ['-created'] + + def __str__(self): + # 展示前20个字符 + return self.content[:20] diff --git a/comment/permissions.py b/comment/permissions.py new file mode 100644 index 0000000..1da9b33 --- /dev/null +++ b/comment/permissions.py @@ -0,0 +1,26 @@ +from rest_framework.permissions import BasePermission, SAFE_METHODS + + +class IsOwnerOrReadOnly(BasePermission): + """ + 只有作者本人可以修改,其他人只能查看 + """ + message = "You must be the owner to update" + + def safe_methods_or_owner(self, request, func): + if request.method in SAFE_METHODS: + return True + return func() + + def has_permission(self, request, view): + return self.safe_methods_or_owner( + request, + lambda: request.user.is_authenticated + ) + + def has_object_permission(self, request, view, obj): + return self.safe_methods_or_owner( + request, + lambda: obj.author == request.user # 验证当前评论的作者和当前登录的用户是否为同一个人 + ) + diff --git a/comment/serializers.py b/comment/serializers.py new file mode 100644 index 0000000..fd9dca0 --- /dev/null +++ b/comment/serializers.py @@ -0,0 +1,15 @@ +from rest_framework import serializers +from user_info.serializers import UserDescSerializer +from comment.models import Comment + + +class CommentSerializer(serializers.ModelSerializer): + """评论的序列化器""" + url = serializers.HyperlinkedIdentityField(view_name='comment-detail') + author = UserDescSerializer(read_only=True) + + class Meta: + model = Comment + fields = '__all__' + extra_kwargs = {'created': {'read_only': True}} + diff --git a/comment/tests.py b/comment/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/comment/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/comment/views.py b/comment/views.py new file mode 100644 index 0000000..472e968 --- /dev/null +++ b/comment/views.py @@ -0,0 +1,14 @@ +from rest_framework import viewsets + +from comment.models import Comment +from comment.serializers import CommentSerializer +from comment.permissions import IsOwnerOrReadOnly + + +class CommentViewSet(viewsets.ModelViewSet): + queryset = Comment.objects.all() + serializer_class = CommentSerializer + permission_classes = [IsOwnerOrReadOnly] + + def perform_create(self, serializer): + serializer.save(author=self.request.user) \ No newline at end of file diff --git a/db.sqlite3 b/db.sqlite3 index 88deac710d2650e3a203c5031426730e7cccf782..5a31d26efa54f23bc5583ac22e9840d591797d72 100644 GIT binary patch delta 2854 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 diff --git a/drf_vue_blog/settings.py b/drf_vue_blog/settings.py index 54baff8..f319c73 100644 --- a/drf_vue_blog/settings.py +++ b/drf_vue_blog/settings.py @@ -1,5 +1,5 @@ from pathlib import Path - +import os # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -29,6 +29,7 @@ INSTALLED_APPS = [ 'article', 'user_info', 'django_filters', + 'comment', ] MIDDLEWARE = [ @@ -115,11 +116,14 @@ STATIC_URL = '/static/' # 使用django_rest_framework中的分页功能 REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', - # 每页3条记录 - 'PAGE_SIZE': 3, + # 每页5条记录 + 'PAGE_SIZE': 5, # 使用django-filter后端过滤引擎 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'], } +# 媒体文件 +MEDIA_URL = '/media/' +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/drf_vue_blog/urls.py b/drf_vue_blog/urls.py index 973784d..15b91da 100644 --- a/drf_vue_blog/urls.py +++ b/drf_vue_blog/urls.py @@ -2,12 +2,16 @@ from django.contrib import admin from django.urls import path, include from rest_framework.routers import DefaultRouter from article import views +from django.conf import settings +from django.conf.urls.static import static +from comment.views import CommentViewSet router = DefaultRouter() router.register(r'article', views.ArticleViewSet) router.register(r'category', views.CategoryViewSet) router.register(r'tag', views.TagViewSet) - +router.register(r'avatar', views.AvatarViewSet) +router.register(r'comment', CommentViewSet) urlpatterns = [ path('admin/', admin.site.urls), @@ -15,3 +19,7 @@ urlpatterns = [ path('api/', include(router.urls)) # path('api/article/', include('article.urls', namespace='article')), ] + +# 把媒体文件的路由注册了 +if settings.DEBUG: + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/media/avatar/20220923/apple_00.png b/media/avatar/20220923/apple_00.png new file mode 100644 index 0000000000000000000000000000000000000000..9a5156d07290d44407553cf89cafc6de318df838 GIT binary patch literal 1006 zcmVC0001)P)t-s0000= z#UV(95NW>>d#V1L{Cr8F7Nya2d#U@9?CP~F6NyH^d#3o6_CPd64mu^f)#V6-Q z9Op(G=SCdUP$=$15$H!9=0+XoM;zxz9p*+I=tmspLK){r9p*+H=Sd*wQY`08B<4mO z=~y)DW=QO5Ozw4D?Q&S_V?^mk8|qs)=~Xc2M;+>3Jne5(>R>?ZY*6S=D7g?*tpET3 zE_6~(Qve@df4|@VZ$F@u(b#{lVP=v;nhMq^yqXX~C~fSL(F(OG<7k&_ zsy4J89qW2jq6Ru`RH$L}bdJ|xrvhDKBY0^~m$??4I=W7SL0U1Mu5p<&0R6Rs5WyM% zW$BV3f;Zs$Gvp6IZ_h1XfjwZU4Rp-*0Dr(*+g+Ii+yOw$U7)4VWi0UrTqgk%AOSxZ zP^RtL2ZEz83FP0&M zcE!oTttpxHzxd6j4G-pEP?U&r|KcyhGg~n1D2W1pZQJl%+kjzalEt5gSGKrQ2I_qL zum{U7P5eoCV+EdFiulbTys-pRK?AHE{@Mpl0s^nG^7yL>XB-hpR-_p&Za|oW&6$Dq zzYS+h!MCGc)t+*>pb(Xb7Os{RuQhTVW@*M9@f zJc4$L&Z^!UfaUoE5Z(fZ=u92jAQF5C3QvCW8*#dpu){NpVf!D|eNO;rPT|pFioOi- z<#?fq#jrib@Zx7s;FV^x-|x2=WJi1+0z9!9h%m&JK}1Ge8X`1t6%bJnmxT!Xc@lt- z_fB9;U`$|4z!KN&i&nxNan%r^-@6^>#HAo&O_(a};qHZ$TE689)H-I6N-2etF+6Wmci8k;~wZK)>ix+7_@6Zuy z>Z?Qw-cWBlFo^z)KNEd{3}z-<0_8JMG?b~)pUWwMo$UQ%*vZ5fACm2wl2KlC2xTx9 z-8e-Ia>r0t#3t|_eg2;R=7ZNHCbtm%LnA{~cwFY{oaAN2>_T*9=uS+gYl|n|7HUnS c(P-4mZ$$2)gBge?`2YX_07*qoM6N<$g3@2mqW}N^ literal 0 HcmV?d00001 diff --git a/media/avatar/20220923/apple_01.png b/media/avatar/20220923/apple_01.png new file mode 100644 index 0000000000000000000000000000000000000000..75ef05713b0c4f80cf8a52187d5d807a30be0723 GIT binary patch literal 1642 zcmX9;X;f2J5PpfEvL&(w$iAq>3W8g4DMTp98X}9qN`dqU9wEVs9~N8B^^zn) zoT$WRqz=<9#z+L_WA)gVT|`YUWk85mbr7_DL}?99QiU59;r@Jr8?464YS+s`HyNmg z;&^R8d9WG-MdV^Elr|*7^$T$?+VCU4;S>!}1pm5+^yV39v<^Gjf|EYRLG31*u>IAz z{wn-n4Nl!jnE9PNQj1l#Lqn0LTJf*CiGMU>XP=XY9`J_JxsR5C~fYd{E;@sQ)B1KU9!v=tAnb)ifDH~(Y1l8_9QkLO8|Ix3yFqjPpA z02t7GJ>5eSVDqw3m`9N5hM{lFqzh{U~2&htlL~0r94POp2sR|0$`Sz*%npn-v%8^~gRg;mka~Ed*dDVR4U@GTg+|vkK zD=w)x&eo{WpAvj3v=tthn`klAmiEI|=M;nOB@DrsNeHTR$>JJHXnarPe65fxITHa$ znpO?e&+Q8un4kH;e`EGFG)8yqsx?silmSn#8|)J>drmVF;T3%dZp;I2D6L{_3&s`D zs)K@JfpOMd^Mx$AdXkoZWbSZWKito`*3r%6&*k=}x9D5dCi~8l4$@b6B0jQ-A+piLM<|OrV zXJOaQwm!ZsYXvc3$TT(=F4Y~B2;Uxh!}2cJ6(W~2*tdJeH)aQ(cHX*OqLz>8GkCIs z#BNNHVC!_5RB?Gl^ULH#r+_n=(mcw7FVZ3k>ur1u3lyRFp}-|st~7kQ#c!2sr>E`b zWUDyxFfdcv0KAu_g?obw#;-UFrn5`OeuQmWY_R*{ZWJAXS zpxw=8?L*L7NxX_0g<~JE_iD`xD3?af&B@+SEV;|?*S_;rX+e2sl=4STMpsxilHZoR zLhID_WKj7k>D?mFeJ?E|Zk<4*r~+~lSFx>!chu(OBZQHTDo8APUB^n&<@5Ze(gVJ- z^l5>h+_Ut$(WBz@kN_rWPi_El$Ax9DBHFkG{z179S8+U~t>}cYpWvw1J0}M9(!(aQ zXHK7DhO^c9Ch7b0rA+%|uC; T>&(yOK@9Nq3iPb@U|#tTY%wqo literal 0 HcmV?d00001 diff --git a/media/avatar/20220923/apple_02.png b/media/avatar/20220923/apple_02.png new file mode 100644 index 0000000000000000000000000000000000000000..e9bdffb43e4720f6f4fb7b8e253dbec21d690fc3 GIT binary patch literal 2092 zcmYLJdpJ~S9R9{MqY%>#rQsa8q|`_*GfWM+M3>z<0Dj`4FuTw#$d3vb0ZT%uP=x34hZZI06O)U~qcJ{Um=!fuaBSa10oX1MlO&Kpc1* z3;K_MZa#Q*81%&g`C-r-1Kz}dp(EgBv~o^Q4Csymia79s58h2BpYuUa6zGWtuVcXT zDDW~$8NeneF&eyx2G63vUx$>XClR1C60}DE8BghS@W2xUJdITP?cty;0<BX= z=p;j%HbeO@NuAl?#_-JKCVudh#X^+5?{}wx;cfvyjyt>?Osq*|Iq$YY%g`9xt{Ui5Oqa!P4F`t z=Dzj%EORJY#9wJOR_0Cco^3wPj%+w`Yw4}Mr1t}ZtZZ_NdW+tS zFLQ!EUe?I=N$|m&8hvfkK5lfquu29QE+n#bN*1IL8i=cW``LR!hlu&{!6eCkV=7Td z?oM#2J-X|5ucODs>VwZ_t+{mKL*jdhMd^ICk2#mMP;W)=)n&-u0=*`SN8R4Xnb{k? zoaz%B1Fe4~>)F_K<~1(J@Jn{vaf#r6U7gK6?S@;Cd1`FtEZfJx&$|8Q)pxFTcdTPW z-=}`5EWT!%dF-9$%B?&7tR^4NPeul|%OlK0Y6F379NYE~ed^b5Mh$_pw`{fK$Guj3 z-b~!e_HI;6rl}eTE$=2&Y%t-<_fN()la7+mz276YUsOA`PiDGKub`>3;xk+Rff|XC7;=qfI;Ws4aoW>K>-j_ zYqO@tVN;8{Zc_Tl*(=VvX{YX=PM#HDSfOXtH+a{yvhazRl>V^X8O_ zrAcRPKl3tmS83pJoc@hvEek2DdncR4u)Cwjz~n`-$NYc#GZelV%O`v~7Y+RWkB*gL z`_n#3q4Rh@Iyig7L|~@&K=5q`(fK;f(^hWooPY}^g$4EIogN23Lb9vIpMDORY9U)B zr+$mW-CgtetkHNjDNhrpv1bT>L^HE6YuWe1dn`Q&AupAhc9pQ6SqP1y1_B0dG?m0l=Cfap=)=CtV(DmZ#Z{Qd@o1r9*Ww5 z=`M3(fbNO$E3_GBKcte>4vtooL03Ywr4KYGmn+9&R;cC75 z#x*WrHL)z%$E#QT;nAV`d`CLJ-EB@o&W@&E_ZhFKt;wEmI8 zTJ4e*?wR4NVq$wKH=L)_B5AC}d+C>sRLj&$XI61enJ>0z=#Iw;r3r)fBUP@)pZ;C# z8ec(I74i2D5Z=>smN7kL%^&F<`tgwjnnzj=^Bl=|VYkYsl+;dz6B*s8_lZek^~IO( zq2;zYZ`synI!1@PLZT5jc)d^dg9VWjPlyS@C$o<}C_M1csF4s!_8A=%u|OI$eOdq%Ny-h`CSB-{F@9WaIX4Ua%?3?e>&cnR?NkYbf z`?M=@cjA|s2gMxt`nwq?Nb=I{*y2Z;UIj14yH!F%LtF0SQmcNw<#AbZ7Q60&y9?8~ JXr2Gje*xyD!7Km( literal 0 HcmV?d00001 diff --git a/media/avatar/20220923/apple_03.png b/media/avatar/20220923/apple_03.png new file mode 100644 index 0000000000000000000000000000000000000000..73df7cb0445c95da026a339759a49539a1943ca7 GIT binary patch literal 1553 zcmYk6doQB5*ry85_ARc)eLM^0y`kp1KtgQj}q{yUn|!jRC?Ec zfj)JsT!>flaf(o(L*yB^VtgH!&@8~!3UD=$_^VzEInz_f{|XA%Uhpxwa(t5ruN2|x%kY;f2&!^Ib1A+-jBh+gXsIN$NpNjd1a&b^0nJzA))pPr zQhcif|0Rd`dAy2eTgl%jrfh=GjX44ze{~$+xTK*;GIS zT+Df{wS*7(sw#Mpn^*BLm8-c;1q)rwMvKm3&N0zKF1q4ZO!*nKh=UPBi$a@oY;;Kx zMhvxBRzjw=kYgrfTb3}b1uV1xf)HU_7jw+hZPD~+~Nz!SsM6Ft+`HE{n`Mg>~ zBI(bQ+1{YPIr(10AiXFOpZGVn|+|y!SS>V9=nlS z0M9=&^!cIh9B0FxBBI|+Qr;NdIO^VZ#M^D(JTbr1b|lD9*WvN4=K}t!s!d^+^*n6k zkYVzCm*26Bf%c+7J6ujrv!k^y^%dPjoU6ag zV494=nh`!v1W`nKH|e7Z{fPj1H=P>2Bj6{cZ}>W*4z>`dN*~fZ$;ML8uHJJ zLo-brq0Ec#Lg9_WCh-8GKx{=$$lx>IPGr?AtR(&azZ-H+%j)Vp-F>{TQAbh0KR z&x*rx1GH(k--ix3kQ0=jHl6wfJli{booPZL-|P8JSDiJ|@aDG5Gf~I|?5Qwmy4AYA z?a#*oANF{iP2G^~k=6J%K-6(Rxuz>6a&tV&@$|{-^PUF@{Vhh3vkq3-0`alb;;tdD zq|QSNw;dk&Ju4C?UA&hc(m%M_Zflx>Uycd6ufX8g&u0#h?@EI@mL0rG((y^j2~Pd= z5tAHM(&A!;b(2}-ZX>CA3IEnS8WunO5MNVr^%OGKMUEspAJj5w%WvSIp6$|6^SFq> zt!#qE0^VCjV>1(0=8_5&&IugFO3XU8WzOXr#%bfap?HhIbjXx;Eb_^fku!|;J;=`O>J8@Cmb=H!G{ zRYpP2faSLk$M77+sq;5Q82$Zy#XFhi{Vbe(5W|JPOoX|rXnJ-NlarHeqO{S` z?MbK6H)Fv2Q5*qLNz)qcjCe(KY6jJZ;c#x#F6BG3&lBnyK1dvW`{9t{Y@>~V{<_ks zi2p7!6@B~I!{J-n6Si2_ASetq=ci6b|C=_hipkJawSVcJknX9Dsj~9eiJs|Ni-Ol= zf5ers^&)}&VnWtXI5_r#obvcz`tp=42YW5;j{t4pU<*ZW;$?x%nMC!FIU7+w$&^e~ z4~kG{wos%R9EeB$sK;t?+x9U9W+{hp@pZlnR$-xrv3Uk;%9MvNk~*+IZW>0Huo(#h z$aE*K%5m+BU@6@0mhauAM?p`6*o2$)+{W;tigej)5~_p8De0zdNslkludPPXw3 z{t*6qR{g}jBivyNN@-GOR=iPgD!T18(_nJYJHV{Y{VFV6ll2G)wz1q|leg>K$nb_0 z+{nwF*V^?6#jfvG9L>@nd)Qay?&?_#9BdDOr!accaKoBH(E8$yk9QPQRU-7|0F;pE J;I<$-`+qO4%jN(8 literal 0 HcmV?d00001 diff --git a/media/avatar/20220923/apple_04.png b/media/avatar/20220923/apple_04.png new file mode 100644 index 0000000000000000000000000000000000000000..29ce42e852f6f6ab8e11702267e471b59d3827d1 GIT binary patch literal 943 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H3?#oinD`S&Jqhp$adq0NXtkbd6_ zR3P%UTkK_r3{duUr{udH(N`T(5C!jg#DG$7x+H+yx8358+Y}zQD?DgZc-}7ix>M?L zoBV@T5cgS&;=?u&<3XF^%XXP3ZE{aK6rZ-s0R@37-*qSfl|2NbM=c7^+GT;_K)o+O z&H&md^S(#)eYg1g9)b70KqLZkf1fbW3l(kpkAVL5DGBlmW{|J9{|^NG>;K2w+uuJg z@2?-f|Nr^<_3!J~-v^4n2TA7tx3AxS|Nr^(>*eD?g8Kja|MS0}pYIQ3pYN~F_m|i2 z-|s(PTmAE51_mZQPZ!6K3dXm$SZCcf5O8>?xjf5arom#_ZPRA{{P$dwW#3eB-O?#b zf9gL-U&eS$BDu#fdA^F ziWT8Unx$4K>7H1$N>lEllWXq>hm6Im^yGpaLv{IF9+`%0J+k=K3a{HY8E**oXD#&S z%D8f2xsu#f$N5SVI2O;Zh!Ot#z`j)W`+B)wUrd?UoUhATCL0)kd~&6$^1!M&Ql*af zXQ@BGV3QDgF89UyeN$K%XBQ>zSi1AyBnyW=hvOBqZ5-Y;u!Ub@KN0(vxxp-QlPh)yA?Vj8M{u|8+OV%nONQr1?L+qc zSbl5!r;SoE){J~CSGNj1$aPGRHe=c)aA%sk{DX$Rt+|sLO1~;CNk2U`m}P(7a#H#>ifjwu7B*TUpxghZk%d{3>@RWMrTJdAy?T!HJ*gy%jCa$xTW;CQhcCB`4_w zcuM+SOmT8}W^qF%aB^9XN2yST{Fkd={h3x4y!{!uN$uyi@YcThbC<3Do%Zs@QGcT! z{%c(rUxhpuYn}-MQEKcY#EUsrr YIk>ET>-F|0z!b^g>FVdQ&MBb@0BbzIDgXcg literal 0 HcmV?d00001 diff --git a/media/avatar/20220923/apple_05.png b/media/avatar/20220923/apple_05.png new file mode 100644 index 0000000000000000000000000000000000000000..9746f295a20f0d653ba00d2e108a038475f741e7 GIT binary patch literal 1619 zcmZ9MdpOg39LIknDUB&9rH-*1r(~&4lx$<#R&oy=6{(yqDwWd}n;q9vPeV8<9ZV;u zvT5#@vN0ottu1WEe#2b5EGd^Ba(QPh8jE{%Tkv)HD<+WKDz0*F!4VfVxA|Egh7%jeu_kdOQ0Ex_XDY z)uSLd+yiz=hBS)4hC;=lvR5GG?PC4g_ykml2_th>rB}@C8`GIdfV&5Fsw|01a>SVFIMFuHdt|wUV#=V9Uq`rgoV<*eyjKJD4>^ z-+@@Jt-Pm$cG1|7Le;jef^o}}F1>r(S1}?<5lmyZeP|;3k=7e3Zj#)N1vnX54tI5tm!HGT~XV`fP)MQ?YF3s$ORR+jmwC%mhT> zc1)56#aWAvBG_XLo&y^%)hTN#m=3Kv$T5E+igE_Sy)ULQlhcK=XEdj>?)MeRe=!c9 zc=BXj#}TAK?g81%qL(YPFPLTb_0Q7z4}Ui`Z9m^#0s}1%v`6ZyMkBWkoW3^mWpYRK z{^^7|W9Ns6+Ht442=wKNqevOXh<%O$fi zM~|dwMu>H4dQUB~sOf4apGp1{PdV@`DjO?mX$l|QB ze<(?843FP>*aY^KIjJu=6F?o>zC4cWy)C!=5ZmkzZGK+)0YO$GyW`@R+d5)v<4^uU zm20j2gx4mc!<%wQ$F1cI#akhQiM)C0{HHMZjfZ*~!$7C&gr(ArcJk-;;*t}Io-KOi zx%wH7&P&+4u5aKQzD5t*tkkc>kNK|{d}lJ??EZ20ws_sEIu+xd^(fSfbM}S5yjf!g z1R=}|lDsocGWRiU%?#?60GUbMXT@>Ha2kIA)wTTY3(R%w0NWgL;rP@&;}Aw5zS)CrO@}48myZX>1Iw`Y zUB+0nN&aj#-qHzWck<%IVnMP474Em)CG*>+imY0ryTB<9F!Aag8`NCn!H^1cU!}T1MkPoq}pVJ<|krmm_oG2^99FGc z^jyu|CclWY99xVy3q);UPoH&&O!=OP*nm6c|~SaACpc{ ZV*ae$M|r8Ap@zOFfac~w=DLJ1{{hc?Ne2J` literal 0 HcmV?d00001 diff --git a/media/avatar/20220923/apple_06.png b/media/avatar/20220923/apple_06.png new file mode 100644 index 0000000000000000000000000000000000000000..d856b29bc4787393ec123b56e3388d99df4371d9 GIT binary patch literal 1314 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 literal 0 HcmV?d00001 diff --git a/media/avatar/20220923/apple_08.png b/media/avatar/20220923/apple_08.png new file mode 100644 index 0000000000000000000000000000000000000000..83ac85742378df461c5c8411c1930685fe0a310d GIT binary patch literal 1420 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 J;I<$-`+qO4%jN(8 literal 0 HcmV?d00001 diff --git a/media/avatar/20220923/apple_20.png b/media/avatar/20220923/apple_20.png new file mode 100644 index 0000000000000000000000000000000000000000..97be381699c7b06ec549d0f0574ada7aab5a09d6 GIT binary patch literal 1241 zcmeAS@N?(olHy`uVBq!ia0vp^jUddy3?whqX(j=wCjmYouK)l4XIRTaJo=-{07pPw za5fsFJB?LgE>~YF>koZ~d9f@4OSyrH-4+3zLwptmvgT#Geqwj zQ%24eJbtYlXI+`(=W^>!<(eDI`o~4)Z;*QNW2qu|=Zw(zEniR`PR< zHGJITj&?fbWu@;4*2p=x+~RomtdE>Wb$@2||33UtbR%D;IP0WJ&MK?-xgYkI-Iuk$ z^7p_IcRSwnTd$J58znlJURbRbe3JOMZ+F<^bN}nlR|IpmtE??=e>Qi@m%FxpDZy0PAWODtmeU*LZg|k5~82Ju^d;6uu^&1wDyVA zpH*V5+-ainrV*3%9Op6@Xl)l#ospYU9PmIYL->pZ!)&piwv*R9*Otf>4w)*Ku=IXj zh2skE2ii9#tx})6q*h>S_Z~6kI48+bJ#I2yjY ztRUKugN3ogi$Oq#&8xx6V#)uyNx^=Swf}F(xeBgl>`%Dx?qH+pgwA@?gLgQ~n)EaG zvqm!6&6|F*!fvLER^1aHHW%}WJV~=ouyFy0rf!UjNduI%zw% z*WuE29sB+N^;O5~^L{UUeAn*D(}K;j&b6Od{7}%;ull9N>W7|nB2tfM7@ByP$S3)H nj_xe{*;Su>ds{9L{btD(eB?0uV!aeF?=pD0`njxgN@xNAPJAeg literal 0 HcmV?d00001