class Post_photo(models.Model): photo = ProcessedImageField(upload_to=post_photo_name, format='JPEG', options={'quality': 60})
class User(AbstractUser): PUBLISHER = 'publisher' STAFF = 'staff' READER = 'reader' USER_TYPES = [ (PUBLISHER, PUBLISHER), (STAFF, STAFF), (READER, READER), ] ENGLISH = 'english' SPANISH = 'spanish' LANGAUGE_CHOICES = [(ENGLISH, ENGLISH), (SPANISH, SPANISH)] FREE = 'free' PREMIUM = 'premium' BETA = 'beta' SUBSCRIPTION_TYPES = [(FREE, FREE), (PREMIUM, PREMIUM), (BETA, BETA)] user_type = models.CharField(max_length=20, choices=USER_TYPES, default=PUBLISHER) phone = models.CharField(max_length=10, default='') publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE, null=True, default=None) profile_pic = models.ImageField(upload_to=profile_pic_path, null=True, default=None) profile_pic_thumbnail = ProcessedImageField( upload_to=profile_pic_path, processors=[ResizeToFill(300, 300)], format='JPEG', options={'quality': 80}, null=True, default=None) #for readers: age = models.PositiveIntegerField(blank=True, null=True) native_langauge = models.CharField(max_length=20, choices=LANGAUGE_CHOICES, default=ENGLISH) secondary_language = models.CharField(max_length=20, choices=LANGAUGE_CHOICES, default=SPANISH) name = models.CharField(max_length=20, null=True, blank=True) subscription_type = models.CharField(max_length=20, choices=SUBSCRIPTION_TYPES, default=FREE) def get_profile_pic(self): if self.profile_pic_thumbnail: return self.profile_pic_thumbnail.url else: return staticfiles_storage.url( 'images/samples/no_profile_image.jpg') def get_best_name(self): if self.first_name: return '{} {}'.format(self.first_name, self.last_name).title() else: return self.username
class Profile(models.Model): def get_dp_path(self, filename): ext = filename.split('.')[-1] filename = "%s.%s" % (uuid.uuid4(), ext) return 'static/uploads/images/dp/' + filename def get_cover_path(self, filename): ext = filename.split('.')[-1] filename = "%s.%s" % (uuid.uuid4(), ext) return 'static/uploads/images/cover/' + filename def get_resume_path(self, filename): ext = filename.split('.')[-1] filename = "%s.%s" % (uuid.uuid4(), ext) return 'static/uploads/documents/resume/' + filename # Basic Info user = models.OneToOneField( User, on_delete=models.CASCADE, related_name='Profile', verbose_name='User', ) email = models.EmailField(max_length=254) phone = models.CharField(max_length=12, blank=True, null=True) first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=50, blank=True, null=True) # Additional Details githubUsername = models.CharField(max_length=50, null=True, blank=True) telegram_id = models.CharField(max_length=50, null=True, blank=True) roll_number = models.CharField(max_length=25, null=True, blank=True) batch = models.IntegerField(null=True, help_text='Year of Admission', blank=True) location = models.CharField(max_length=150, null=True, blank=True) birthday = models.DateField(null=True, help_text='YYYY-MM-DD', blank=True) tagline = models.CharField(max_length=80, null=True, blank=True) about = RichTextField(max_length=1000, null=True, blank=True) typing_speed = models.IntegerField(null=True, blank=True) resume = models.FileField( upload_to=get_resume_path, verbose_name='Attach Resume', null=True, blank=True, validators=[validate_file_size] ) system_no = models.IntegerField(null=True, blank=True) cover = ProcessedImageField( default='', blank=True, verbose_name='Cover Picture', upload_to=get_cover_path, validators=[validate_file_size], **processed_image_field_specs, null=True, ) accent = models.CharField( max_length=15, verbose_name='Accent Colour for Profile', help_text='Hex value with #', blank=True, null=True ) # Relational Fields languages = models.ManyToManyField(Language, blank=True) interests = models.ManyToManyField(Skill, related_name='interests', blank=True) expertise = models.ManyToManyField(Skill, related_name='expertise', blank=True) experiences = models.ManyToManyField(Organization, related_name='WorkExperiences', through='WorkExperience') qualifications = models.ManyToManyField( Organization, related_name='EducationalQualifications', through='EducationalQualification' ) links = models.ManyToManyField(Portal, related_name='SocialProfile', through='SocialProfile') class Meta: verbose_name_plural = "Profiles" verbose_name = "Profile" def __str__(self): return self.first_name
class Event(EsIndexable, models.Model): """ Event model represents exactly real question which you can answer YES or NO. """ IN_PROGRESS, CANCELLED, FINISHED_YES, FINISHED_NO = range(1, 5) EVENT_OUTCOME_CHOICES = ( (IN_PROGRESS, u'w trakcie'), (CANCELLED, u'anulowane'), (FINISHED_YES, u'rozstrzygnięte na TAK'), (FINISHED_NO, u'rozstrzygnięte na NIE'), ) EVENT_FINISHED_TYPES = (CANCELLED, FINISHED_YES, FINISHED_NO) BOOLEAN_OUTCOME_DICT = {FINISHED_YES: True, FINISHED_NO: False} BEGIN_PRICE = 50 FACTOR_B = 10 PRIZE_FOR_WINNING = 100 CHART_MARGIN = 3 EVENT_SMALL_CHART_DAYS = 14 EVENT_BIG_CHART_DAYS = 28 SMALL_IMAGE_WIDTH = 340 SMALL_IMAGE_HEIGHT = 250 BIG_IMAGE_WIDTH = 1250 BIG_IMAGE_HEIGHT = 510 snapshots = SnapshotAddon(fields=[ 'current_buy_for_price', 'current_buy_against_price', 'current_sell_for_price', 'current_sell_against_price', 'Q_for', 'Q_against', 'B' ]) title = models.CharField(u'tytuł wydarzenia', max_length=255) short_title = models.CharField(verbose_name=u'tytuł promocyjny wydarzenia', max_length=255, default='', blank=True) description = models.TextField(u'pełny opis wydarzenia', default='') categories = models.ManyToManyField('events.EventCategory', verbose_name=u'kategorie', blank=True) is_featured = models.BooleanField(u'wyróżniony', default=False) is_published = models.BooleanField(u'opublikowano', default=True) twitter_tag = models.CharField( verbose_name=u'tag twittera', max_length=32, null=True, blank=True, default='', validators=[ RegexValidator(regex=r'^([^\s]+)$', message=u'Tag twittera nie może zawierać spacji', code='invalid_twitter_tag'), ]) title_fb_yes = models.CharField(u'tytuł na TAK obiektu FB', max_length=255, default='', blank=True, null=True) title_fb_no = models.CharField(u'tytuł na NIE obiektu FB', max_length=255, default='', blank=True, null=True) small_image = ProcessedImageField( help_text=u'mały obrazek {0}x{1}'.format(SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT), upload_to='events_small', processors=[ResizeToFill(SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT)], null=True, blank=False, ) big_image = ProcessedImageField( help_text=u'duży obrazek {0}x{1}'.format(BIG_IMAGE_WIDTH, BIG_IMAGE_HEIGHT), upload_to='events_big', processors=[ResizeToFill(BIG_IMAGE_WIDTH, BIG_IMAGE_HEIGHT)], null=True, blank=False, ) # głosowanie do rozstrzygania wydarzeń vote_yes_count = models.PositiveIntegerField(u'głosów na tak', default=0) vote_no_count = models.PositiveIntegerField(u'głosów na nie', default=0) vote_cancel_count = models.PositiveIntegerField(u'głosów na anuluj', default=0) outcome = models.PositiveIntegerField(u'rozstrzygnięcie', choices=EVENT_OUTCOME_CHOICES, default=1) outcome_reason = models.TextField(u'uzasadnienie wyniku', default='', blank=True) created_date = models.DateTimeField(auto_now_add=True, verbose_name=u'data utworzenia') created_by = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'utworzone przez', null=True, related_name='created_by') estimated_end_date = models.DateTimeField( u'przewidywana data rozstrzygnięcia', null=True, blank=False) end_date = models.DateTimeField(u'data rozstrzygnięcia', null=True, blank=True) current_buy_for_price = models.IntegerField( u'cena nabycia akcji zdarzenia', default=BEGIN_PRICE) current_buy_against_price = models.IntegerField( u'cena nabycia akcji zdarzenia przeciwnego', default=BEGIN_PRICE) current_sell_for_price = models.IntegerField( u'cena sprzedaży akcji zdarzenia', default=BEGIN_PRICE) current_sell_against_price = models.IntegerField( u'cena sprzedaży akcji zdarzenia przeciwnego', default=BEGIN_PRICE) last_transaction_date = models.DateTimeField(u'data ostatniej transakcji', null=True) Q_for = models.IntegerField(u'zakładów na TAK', default=0) Q_against = models.IntegerField(u'zakładów na NIE', default=0) turnover = models.IntegerField(u'obrót', default=0, db_index=True) absolute_price_change = models.IntegerField( u'zmiana ceny (wartość absolutna)', db_index=True, default=0) price_change = models.IntegerField(u'zmiana ceny', default=0) # constant for calculating event change # probably: how you need to increment quantity, to change price B = models.FloatField(u'stała B', default=FACTOR_B) objects = EventManager() tags = TaggableManager(blank=True) class Meta: verbose_name = 'wydarzenie' verbose_name_plural = 'wydarzenia' def __unicode__(self): return self.title def save(self, *args, **kwargs): """ Recalculate prices for event :param kwargs: """ if not self.pk: self.recalculate_prices() super(Event, self).save(*args, **kwargs) def get_absolute_url(self): return 'http://%(domain)s%(url)s' % { 'domain': current_domain(), 'url': reverse('events:event_detail', kwargs={'pk': self.pk}) } def get_relative_url(self): return '/event/%(id)d-%(title)s' % { 'id': self.id, 'title': slugify(unidecode(self.title)) } def get_absolute_facebook_object_url(self): return 'http://%(domain)s%(url)s' % { 'domain': current_domain(), 'url': reverse('events:event_facebook_object_detail', kwargs={'event_id': self.id}) } def get_small_embed_url(self): return 'http://%(domain)s%(url)s' % { 'domain': current_domain(), 'url': reverse('events:event_embed_detail', kwargs={'pk': self.id}) } @staticmethod def autocomplete_search_fields(): return ("id__iexact", "title__icontains", "short_title__icontains") @property def is_in_progress(self): return self.outcome == Event.IN_PROGRESS @property def publish_channel(self): return 'event_%d' % self.id @property def event_dict(self): return { 'event_id': self.id, 'buy_for_price': self.current_buy_for_price, 'buy_against_price': self.current_buy_against_price, 'sell_for_price': self.current_sell_for_price, 'sell_against_price': self.current_sell_against_price, } @property def finish_date(self): """ If event is not finished then estimated_end_date, else end_date :return: finish date :rtype: datetime """ if self.is_in_progress: return self.estimated_end_date else: return self.end_date def price_for_outcome(self, outcome, direction=True): if (direction, outcome) not in Bet.BET_OUTCOMES_TO_PRICE_ATTR: raise UnknownOutcome() attr = Bet.BET_OUTCOMES_TO_PRICE_ATTR[(direction, outcome)] return getattr(self, attr) def get_event_small_chart(self): """ Get last transactions price for every day from small event range :return: chart points of EVENT_SMALL_CHART_DAYS days :rtype: {int, [], []} """ return self.__get_chart_points(self.EVENT_SMALL_CHART_DAYS) def get_event_big_chart(self): """ Get last transactions price for every day from big event range :return: chart points of EVENT_BIG_CHART_DAYS days :rtype: {int, [], []} """ return self.__get_chart_points(self.EVENT_BIG_CHART_DAYS) def get_JSON_small_chart(self): return json.dumps(self.get_event_small_chart()) def get_JSON_big_chart(self): return json.dumps(self.get_event_big_chart()) @transaction.atomic def __get_chart_points(self, days): """ Get last transactions price for every day; :param days: number of days in past on chart :type days: int :return: chart points :rtype: {int, [], []} """ last_date = self.end_date if self.end_date else timezone.now() first_date = max(last_date - relativedelta(days=days), self.created_date) labels = [] points = [] snapshots = self.snapshots.filter( snapshot_of_id=self.id, created_at__gte=first_date, created_at__lte=last_date, created_at__hour=0).order_by('created_at') additional_points = min(days - len(snapshots), Event.CHART_MARGIN) step_date = first_date - relativedelta(days=additional_points) for point in range(additional_points): labels.append(u'{0} {1}'.format(step_date.day, _(step_date.strftime('%B')))) step_date += relativedelta(days=1) points.append(Event.BEGIN_PRICE) for snapshot in snapshots: labels.append(u'{0} {1}'.format( snapshot.created_at.day, _(snapshot.created_at.strftime('%B')))) last_price = snapshot.current_buy_for_price points.append(last_price) return {'id': self.id, 'labels': labels, 'points': points} def get_user_bet_object(self, user): """ find not empty just only one bet object or None :param user: logged user :type user: User :return: normally it should returns one bet where bet.has > 0 :rtype: Bet or None """ bets = self.bets.filter(user=user, has__gt=0).order_by('-id') if bets.exists(): return bets[0] def get_user_bet(self, user): """ get bet summary for user; user maybe anonymous. :param user: logged user or anonymous :type user: User :return: data for one bet display :rtype: {} """ # Using 'true' and 'false' because some keys are designed for json bet_line = { 'is_user': False, 'has': 0, 'avgPrice': 0, 'outcome': None, # note: None is the same as False 'buyNO': 'true', # default option is buy bet 'buyYES': 'true', # default option is buy bet 'priceYES': self.current_buy_for_price, 'priceNO': self.current_buy_against_price, } if user.pk: bet_line['is_user'] = True bet = self.get_user_bet_object(user) if bet: bet_line['id'] = bet.pk # it is only for debugging purpose bet_line['has'] = bet.has bet_line['avgPrice'] = bet.bought_avg_price bet_line[ 'outcome'] = bet.outcome # True - YES False - NO if bet.outcome: # you have bet for YES, you can sell them bet_line['buyNO'] = 'false' # that means you sell bet YES bet_line['priceYES'] = self.current_buy_for_price bet_line['priceNO'] = self.current_sell_for_price bet_line['outcome_str'] = 'true' else: # you have bet for NO, you can sell them bet_line['buyYES'] = 'false' # that means you sell bet NO bet_line['priceYES'] = self.current_sell_against_price bet_line['priceNO'] = self.current_buy_against_price bet_line['outcome_str'] = 'false' return bet_line def get_bet_social(self): """ Get users who bought this event :return: Dict with 4 keys: 2 QuerySet with YES users and NO users, 2 integers with counts :rtype: dict{} """ response = {} bet_social_yes = Bet.objects.filter( event=self, outcome=True, # bought YES has__gt=0, ) response['yes_count'] = bet_social_yes.count() response['yes_bets'] = bet_social_yes[:6] bet_social_no = Bet.objects.filter( event=self, outcome=False, # bought NO has__gt=0, ) response['no_count'] = bet_social_no.count() response['no_bets'] = bet_social_no[:6] return response def increment_quantity(self, outcome, by_amount): """ Used when operation buy or sell occurs :param outcome: event outcome - YES or NO; True for YES :type outcome: bool :param by_amount: operations count, usually 1 :type by_amount: int :return: """ if outcome not in Bet.BET_OUTCOMES_TO_QUANTITY_ATTR: raise UnknownOutcome() attr = Bet.BET_OUTCOMES_TO_QUANTITY_ATTR[outcome] setattr(self, attr, getattr(self, attr) + by_amount) self.recalculate_prices() def increment_turnover(self, by_amount): """ Turnover increases +1 when operation buy or sell occurs :param by_amount: operations count, usually 1 :type by_amount: int """ self.turnover += by_amount def recalculate_prices(self): """ Calculate 4 prices for event """ factor = 100. B = self.B Q_for = self.Q_for Q_against = self.Q_against Q_for_sell = max(0, Q_for - 1) Q_against_sell = max(0, Q_against - 1) e_for_buy = exp(Q_for / B) e_against_buy = exp(Q_against / B) e_for_sell = exp(Q_for_sell / B) e_against_sell = exp(Q_against_sell / B) buy_for_price = e_for_buy / float(e_for_buy + e_against_buy) buy_against_price = e_against_buy / float(e_for_buy + e_against_buy) sell_for_price = e_for_sell / float(e_for_sell + e_against_buy) sell_against_price = e_against_sell / float(e_for_buy + e_against_sell) self.current_buy_for_price = round(factor * buy_for_price, 0) self.current_buy_against_price = round(factor * buy_against_price, 0) self.current_sell_for_price = round(factor * sell_for_price, 0) self.current_sell_against_price = round(factor * sell_against_price, 0) def vote_yes(self): self.vote_yes_count += 1 if self.vote_yes_count >= config.VOICES_TO_RESOLVE: self.finish_yes() self.save() return self.vote_yes_count def vote_no(self): self.vote_no_count += 1 if self.vote_no_count >= config.VOICES_TO_RESOLVE: self.finish_no() self.save() return self.vote_no_count def vote_cancel(self): self.vote_cancel_count += 1 if self.vote_cancel_count >= config.VOICES_TO_RESOLVE: self.cancel() self.save() return self.vote_cancel_count @transaction.atomic def __finish(self, outcome): """ Set Event finish status :param outcome: outcome status; EVENT_OUTCOME_CHOICES :type outcome: Choices """ if self.outcome != self.IN_PROGRESS: raise EventNotInProgress("Wydarzenie zostało już rozwiązane.") self.outcome = outcome self.end_date = timezone.now() self.save() @transaction.atomic def __finish_with_outcome(self, outcome): """ main finish status :param outcome: outcome status; EVENT_OUTCOME_CHOICES :type outcome: Choices """ self.__finish(outcome) for bet in Bet.objects.filter(event=self): if bet.outcome == self.BOOLEAN_OUTCOME_DICT[outcome]: bet.rewarded_total = self.PRIZE_FOR_WINNING * bet.has bet.user.total_cash += bet.rewarded_total Transaction.objects.create(user=bet.user, event=self, type=Transaction.EVENT_WON_PRIZE, quantity=bet.has, price=self.PRIZE_FOR_WINNING) # TODO: tutaj wallet change # bet.user.portfolio_value -= bet.has bet.user.save() # This cause display event in "latest outcome" bet.is_new_resolved = True bet.save() @transaction.atomic def finish_yes(self): """ if event is finished on YES then prizes calculate """ self.__finish_with_outcome(self.FINISHED_YES) @transaction.atomic def finish_no(self): """ if event is finished on NO then prizes calculate """ self.__finish_with_outcome(self.FINISHED_NO) @transaction.atomic def cancel(self): """ refund for users on cancel event. """ self.__finish(self.CANCELLED) users = {} for t in Transaction.objects.filter(event=self).order_by('user'): if t.user not in users: users.update({t.user: 0}) if t.type in Transaction.BUY_SELL_TYPES: # for transaction type BUY the price is below 0 that means refund should be # other side. For BUY (buy is always -) refund should be (+) (EVENT_CANCELLED_REFUND) # but for BUY and SELL with profit refund should be (-) (EVENT_CANCELLED_DEBIT) users[t.user] -= t.quantity * t.price for user, refund in users.iteritems(): if refund == 0: continue user.total_cash += refund user.save() if refund > 0: transaction_type = Transaction.EVENT_CANCELLED_REFUND else: transaction_type = Transaction.EVENT_CANCELLED_DEBIT Transaction.objects.create(user=user, event=self, type=transaction_type, price=refund)
class Image(models.Model): order_number = models.PositiveIntegerField( verbose_name='Order number of the image') caption = models.TextField( blank=True, null=True, verbose_name='Caption text for the image', help_text= 'Text to show at the bottom of the image. You may use MarkDown here.') image = ProcessedImageField( upload_to='carousel', processors=[ResizeToFill(640, 480)], format='JPEG', options={'quality': 90}, verbose_name='Image file', help_text= 'Pick up a image file from your computer. Image should be big enough so that it wont get scaled up by the system.' ) @classmethod def max_order_number(cls): return Image.objects.all().aggregate( models.Max('order_number'))['order_number__max'] def __unicode__(self): return self.caption class Meta: ordering = ['order_number'] def __init__(self, *args, **kwargs): super(Image, self).__init__(*args, **kwargs) if not self.pk: self.to_the_end() def caption_html(self): return markdown.markdown(self.caption, extensions=['markdown.extensions.nl2br']) def delete(self, *args, **kwargs): self.slice_off() return super(Image, self).delete(*args, **kwargs) def to_the_end(self): max_order_number = Image.max_order_number() self.order_number = 0 if max_order_number is not None: self.order_number = max_order_number + 1 def reorder(self, new_order_number): self.slice_off() self.push_between(new_order_number) def slice_off(self): Image.objects.filter(order_number__gt=self.order_number).update( order_number=models.F('order_number') - 1) def push_between(self, new_order_number): Image.objects.filter(order_number__gte=new_order_number).exclude( pk=self.pk).update(order_number=models.F('order_number') + 1) self.order_number = new_order_number self.save()
class Video(models.Model): PROCESSING, PUBLISHED, PRIVATE, MANAGER, DELETED, CLOSED = '_PRO','PUB','PRI', 'MAN', '_DEL', '_CLO' DELETED_PRIVATE, DELETED_MANAGER, CLOSED_PRIVATE, CLOSED_MANAGER = '_DELP', '_DELM', '_CLOP', '_CLOM' TYPE = ( (PROCESSING, 'Обработка'),(PUBLISHED, 'Опубликовано'),(DELETED, 'Удалено'),(PRIVATE, 'Приватно'),(CLOSED, 'Закрыто модератором'),(MANAGER, 'Созданный персоналом'), (DELETED_PRIVATE, 'Удалённый приватный'),(DELETED_MANAGER, 'Удалённый менеджерский'),(CLOSED_PRIVATE, 'Закрытый приватный'),(CLOSED_MANAGER, 'Закрытый менеджерский'), ) image = ProcessedImageField(format='JPEG', options={'quality': 90}, upload_to=upload_to_video_directory, processors=[ResizeToFit(width=500, upscale=False)], verbose_name="Обложка",blank=True, null=True) created = models.DateTimeField(auto_now_add=True, auto_now=False, verbose_name="Создан") description = models.CharField(max_length=500, blank=True, verbose_name="Описание") category = models.ForeignKey(VideoCategory, blank=True, null=True, related_name='video_category', on_delete=models.CASCADE, verbose_name="Категория") title = models.CharField(max_length=255, verbose_name="Название") uri = models.CharField(max_length=255, blank=True, null=True, verbose_name="Ссылка на видео") uuid = models.UUIDField(default=uuid.uuid4, verbose_name="uuid") list = models.ManyToManyField(VideoList, related_name="video_list", blank=True, verbose_name="Альбом") media_list = models.ManyToManyField("lists.MediaList", related_name='video_media_list', blank=True, verbose_name="Медиа-список") creator = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="video_creator", on_delete=models.CASCADE, verbose_name="Создатель") type = models.CharField(choices=TYPE, default=PROCESSING, max_length=5) file = models.FileField(upload_to=upload_to_video_directory, blank=True, null=True, validators=[validate_file_extension], verbose_name="Видеозапись") community = models.ForeignKey('communities.Community', related_name='video_community', on_delete=models.CASCADE, null=True, blank=True, verbose_name="Сообщество") is_video = models.BooleanField(default=True) class Meta: verbose_name = "Видео-ролики" verbose_name_plural = "Видео-ролики" indexes = (BrinIndex(fields=['created']),) ordering = ['-created'] def __str__(self): return self.title def get_mime_type(self): import magic file = self.file initial_pos = file.tell() file.seek(0) mime_type = magic.from_buffer(file.read(1024), mime=True) file.seek(initial_pos) return mime_type @classmethod def create_video(cls, creator, title, file, image, uri, lists, is_public, community): from common.processing import get_video_processing if not lists: from rest_framework.exceptions import ValidationError raise ValidationError("Не выбран список для нового документа") elif not file and not uri: from rest_framework.exceptions import ValidationError raise ValidationError("Не выбран файл для ссылка") if uri: current_uri = uri.replace("watch?v=", "embed/") else: current_uri = "" private = 0 video = cls.objects.create(creator=creator,title=title,image=image,file=file,uri=current_uri,community=community) if community: community.plus_videos(1) else: creator.plus_videos(1) for list_id in lists: video_list = VideoList.objects.get(pk=list_id) video_list.video_list.add(video) if video_list.is_private(): private = 1 if not private and is_public: get_video_processing(video, Video.PUBLISHED) if community: from common.notify.progs import community_send_notify, community_send_wall from notify.models import Notify, Wall #Wall.objects.create(creator_id=creator.pk, community_id=community.pk, recipient_id=user_id, type="VID", object_id=video.pk, verb="ITE") #community_send_wall(video.pk, creator.pk, community.pk, None, "create_c_video_wall") for user_id in community.get_member_for_notify_ids(): Notify.objects.create(creator_id=creator.pk, community_id=community.pk, recipient_id=user_id, type="VID", object_id=video.pk, verb="ITE") community_send_notify(video.pk, creator.pk, user_id, community.pk, None, "create_c_video_notify") else: from common.notify.progs import user_send_notify, user_send_wall from notify.models import Notify, Wall #Wall.objects.create(creator_id=creator.pk, type="VID", object_id=video.pk, verb="ITE") #user_send_wall(video.pk, None, "create_u_video_wall") for user_id in creator.get_user_news_notify_ids(): Notify.objects.create(creator_id=creator.pk, recipient_id=user_id, type="VID", object_id=video.pk, verb="ITE") user_send_notify(video.pk, creator.pk, user_id, None, "create_u_video_notify") else: get_video_processing(video, Video.PRIVATE) return video @classmethod def create_manager_video(cls, creator, title, file, image, uri, lists): from common.processing import get_video_processing from logs.model.manage_video import VideoManageLog from lists.models import MediaList if not lists: from rest_framework.exceptions import ValidationError raise ValidationError("Не выбран список для нового документа") elif not file and not uri: from rest_framework.exceptions import ValidationError raise ValidationError("Не выбран файл для ссылка") if uri: current_uri = uri.replace("watch?v=", "embed/") else: current_uri = "" video = cls.objects.create(creator=creator,title=title,image=image,file=file,uri=current_uri) for list_id in lists: list = MediaList.objects.get(pk=list_id) video.media_list.add(list) list.count += 1 list.save(update_fields=["count"]) get_video_processing(video, Video.MANAGER) VideoManageLog.objects.create(item=video.pk, manager=creator.pk, action_type=VideoManageLog.ITEM_CREATED) return video def edit_video(self, title, uri, image, file, lists, is_public): from common.processing import get_video_processing self.title = title self.file = file self.lists = lists self.uri = uri self.image = image if is_public: get_video_processing(self, Video.PUBLISHED) self.make_publish() else: get_video_processing(self, Video.PRIVATE) self.make_private() return self.save() def edit_manager_video(self, title, uri, image, file, lists, manager_id): from common.processing import get_video_processing from logs.model.manage_video import VideoManageLog self.title = title self.file = file self.lists = lists self.uri = uri self.image = image get_video_processing(self, Video.MANAGER) VideoManageLog.objects.create(item=self.pk, manager=manager_id, action_type=VideoManageLog.ITEM_EDITED) return self.save() def get_uri(self): if self.file: return self.file.url else: return self.uri def get_created(self): from django.contrib.humanize.templatetags.humanize import naturaltime return naturaltime(self.created) def likes(self): return VideoVotes.objects.filter(parent_id=self.pk, vote__gt=0) def visits_count_ru(self): count = self.all_visits_count() a = count % 10 b = count % 100 if (a == 1) and (b != 11): return str(count) + " просмотр" elif (a >= 2) and (a <= 4) and ((b < 10) or (b >= 20)): return str(count) + " просмотра" else: return str(count) + " просмотров" def all_visits_count(self): from stst.models import VideoNumbers return VideoNumbers.objects.filter(video=self.pk).values('pk').count() def get_lists(self): return self.list.all() def get_list_uuid(self): return self.list.all()[0].uuid def get_media_lists(self): return self.media_list.all() def is_item_in_user_media_list(self, user_id): from lists.models import MediaList if MediaList.objects.filter(owner_id=user_id).exists(): list = MediaList.objects.filter(owner_id=user_id)[0] return list.is_video_in_list(self.pk) return False def make_private(self): from notify.models import Notify, Wall self.type = Video.PRIVATE self.save(update_fields=['type']) if Notify.objects.filter(type="VID", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="VID", object_id=self.pk, verb="ITE").update(status="C") #if Wall.objects.filter(type="VID", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="VID", object_id=self.pk, verb="ITE").update(status="C") def make_publish(self): from notify.models import Notify, Wall self.type = Video.PUBLISHED self.save(update_fields=['type']) if Notify.objects.filter(type="VID", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="VID", object_id=self.pk, verb="ITE").update(status="R") #if Wall.objects.filter(type="VID", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="VID", object_id=self.pk, verb="ITE").update(status="R") def delete_video(self, community): from notify.models import Notify, Wall if self.type == "PUB": self.type = Video.DELETED elif self.type == "PRI": self.type = Video.DELETED_PRIVATE elif self.type == "MAN": self.type = Video.DELETED_MANAGER self.save(update_fields=['type']) if community: community.minus_videos(1) else: self.creator.minus_videos(1) if Notify.objects.filter(type="VID", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="VID", object_id=self.pk, verb="ITE").update(status="C") #if Wall.objects.filter(type="VID", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="VID", object_id=self.pk, verb="ITE").update(status="C") def abort_delete_video(self, community): from notify.models import Notify, Wall if self.type == "_DEL": self.type = Video.PUBLISHED elif self.type == "_DELP": self.type = Video.PRIVATE elif self.type == "_DELM": self.type = Video.MANAGER self.save(update_fields=['type']) if community: community.plus_videos(1) else: self.creator.plus_videos(1) if Notify.objects.filter(type="VID", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="VID", object_id=self.pk, verb="ITE").update(status="R") #if Wall.objects.filter(type="VID", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="VID", object_id=self.pk, verb="ITE").update(status="R") def close_item(self, community): from notify.models import Notify, Wall if self.type == "PUB": self.type = Video.CLOSED elif self.type == "PRI": self.type = Video.CLOSED_PRIVATE elif self.type == "MAN": self.type = Video.CLOSED_MANAGER self.save(update_fields=['type']) if community: community.minus_videos(1) else: self.creator.minus_videos(1) if Notify.objects.filter(type="VID", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="VID", object_id=self.pk, verb="ITE").update(status="C") #if Wall.objects.filter(type="VID", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="VID", object_id=self.pk, verb="ITE").update(status="C") def abort_close_item(self, community): from notify.models import Notify, Wall if self.type == "_CLO": self.type = Video.PUBLISHED elif self.type == "_CLOP": self.type = Video.PRIVATE elif self.type == "_CLOM": self.type = Video.MANAGER self.save(update_fields=['type']) if community: community.plus_videos(1) else: self.creator.plus_videos(1) if Notify.objects.filter(type="VID", object_id=self.pk, verb="ITE").exists(): Notify.objects.filter(type="VID", object_id=self.pk, verb="ITE").update(status="R") #if Wall.objects.filter(type="VID", object_id=self.pk, verb="ITE").exists(): # Wall.objects.filter(type="VID", object_id=self.pk, verb="ITE").update(status="R") def is_private(self): return self.type == self.PRIVATE def is_open(self): return self.type == self.MANAGER or self.type == self.PUBLISHED def is_deleted(self): return self.type[:4] == "_DEL" def is_closed(self): return self.type[:4] == "_CLO" def is_suspended(self): return False def get_image(self): if self.image: return self.image.url else: return "/static/images/list.jpg"
class Entity(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) user = models.OneToOneField(User, null=False, blank=False) city = models.ForeignKey(City, null=False, blank=False) cif = models.CharField(null=True, blank=True, verbose_name='NIF/CIF', max_length=50) email = models.CharField(null=False, blank=False, verbose_name='Email', max_length=250) name = models.CharField(null=True, blank=True, verbose_name='Nombre', max_length=250) description = models.TextField(null=True, blank=True, verbose_name='Descripción') short_description = models.TextField(null=True, blank=True, verbose_name='Descripción corta') phone_number = models.CharField(null=True, blank=True, verbose_name='Teléfono', max_length=25) address = models.TextField(null=True, blank=True, verbose_name='Dirección') logo = ProcessedImageField(null=True, blank=True, upload_to=RandomFileName('entities/'), verbose_name='Imagen de perfil', processors=[ResizeToFit(512, 512, upscale=False)], format='JPEG') logo_thumbnail = ImageSpecField(source='logo', processors=[ResizeToFill(150, 150, upscale=False)], format='JPEG', options={'quality': 70}) registered = models.DateTimeField(auto_now_add=True) latitude = models.FloatField(null=False, verbose_name='Latitud', default=0) longitude = models.FloatField(null=False, verbose_name='Longitud', default=0) categories = models.ManyToManyField(Category, blank=True, verbose_name='Categorías') # Currency fields bonus_percent_entity = models.FloatField(default=0, verbose_name='Porcentaje de bonificación a entidades', validators = [MinValueValidator(0), MaxValueValidator(100)]) bonus_percent_general = models.FloatField(default=0, verbose_name='Porcentaje de bonificación general', validators = [MinValueValidator(0), MaxValueValidator(100)]) max_percent_payment = models.FloatField(default=0, verbose_name='Máximo porcentaje de pago aceptado', validators = [MinValueValidator(0), MaxValueValidator(100)]) num_workers = models.IntegerField(default=0, verbose_name='Número de trabajadores', validators = [MinValueValidator(0)]) legal_form = models.TextField(null=True, blank=True, verbose_name='Formulario legal') # Social links facebook_link = models.CharField(null=True, blank=True, verbose_name='Página de Facebook', max_length=250) webpage_link = models.CharField(null=True, blank=True, verbose_name='Página web', max_length=250) twitter_link = models.CharField(null=True, blank=True, verbose_name='Perfil de Twitter', max_length=250) telegram_link = models.CharField(null=True, blank=True, verbose_name='Canal de Telegram', max_length=250) instagram_link = models.CharField(null=True, blank=True, verbose_name='Perfil de Instagram', max_length=250) inactive = models.BooleanField(default=False, verbose_name='Inactiva') hidden = models.BooleanField(default=False, verbose_name='Oculta') gallery = models.OneToOneField(Gallery, blank=True, null=True, on_delete=models.SET_NULL) objects = EntityManager() @property def display_name(self): return self.name @property def first_photo_url(self): if self.gallery and self.gallery.photos.count() > 0: image = self.gallery.photos.all().first() if image: return image.image.url return None @property def qr_code(self): return settings.BASESITE_URL + reverse('entity_qr_detail', kwargs={'pk': self.pk} ) def bonus(self, total_amount, bonusable_type=None): percent = self.bonus_percent_general if bonusable_type == 'entity': percent = self.bonus_percent_entity return round(total_amount * (percent / 100.0), 2) def max_accepted_currency(self, total_amount): return round(total_amount * (self.max_percent_payment / 100.0), 2) class Meta: verbose_name = 'Entidad' verbose_name_plural = 'Entidades' ordering = ['name'] def __unicode__(self): return self.name if self.name else 'Entidad'
class BlogEntry(LikedModel, BaseModel): """Model to store one blog entry.""" is_active = models.BooleanField( default=True, verbose_name=_('Is active'), ) title = models.CharField( max_length=255, null=True, blank=False, verbose_name=_('Title'), ) subtitle = models.CharField( max_length=255, null=True, blank=True, verbose_name=_('Subtitle'), ) slug = models.CharField( blank=False, db_index=True, max_length=64, null=True, unique=True, verbose_name=_('Slug'), ) description = models.TextField( null=True, blank=True, verbose_name=_('Description'), help_text=_('Short description of blog entry'), ) image = ProcessedImageField( null=True, blank=True, processors=[ResizeToFit(960, 540)], format='JPEG', options={'quality': 100}, upload_to=BaseModel.obfuscated_upload, verbose_name=_('Image'), ) thumbnail = ImageSpecField( source='image', processors=[ResizeToFit(400, 400)], format='JPEG', options={'quality': 100}, ) video = models.ForeignKey( 'files.VideoFile', null=True, blank=True, on_delete=models.SET_NULL, related_name='blog_enties', verbose_name=_('Video'), ) text = models.TextField( null=True, blank=True, verbose_name=_('Text'), help_text=_('Main blog text'), ) date = models.DateTimeField( blank=False, verbose_name=_('Date'), ) show_gallery = models.BooleanField( default=False, verbose_name=_('Show gallery'), ) category = models.ForeignKey( BlogCategory, null=True, blank=True, on_delete=models.SET_NULL, related_name='blogs', verbose_name=_('Category'), ) def __str__(self): return self.title or '-' class Meta: verbose_name = _('Blog entry') verbose_name_plural = _('Blog entries') ordering = ('-date',) def get_absolute_url(self): """Get absolute URL for sitemap.""" return f'/video/{self.slug}' # Blog series navigation # ======================================================================== @property def date_str(self): return ru_date_format(self.date, '%d %RSM. %Y') @property def is_series(self): return self.series_item.exists() @property def series(self): return self.series_item.first().series @property def next(self): return self._get_part(index=1) @property def prev(self): return self._get_part(index=-1) @property def duration(self): """Get video duration if it exists.""" return self.video.duration if self.video else None def _get_part(self, index): order = self.series_item.first().order + index return self.series.items.filter(order=order).first()
class Ad(models.Model): photo = ProcessedImageField(upload_to=ad_photo_name, format='JPEG') link = models.CharField(max_length=100)
class Tool(models.Model): class Meta: app_label = 'app' def toolPictureName(instance, filename): ext = filename.split('.')[-1] return 'toolpics/{}.{}'.format(instance.name, ext) name = models.CharField(max_length=25) picture = ProcessedImageField(processors=[Resize(500, 500)], format='JPEG', upload_to=toolPictureName) description = models.TextField(max_length=500) status = models.CharField(max_length=1, choices=app.constants.TOOL_STATUS) category = models.CharField(max_length=2, choices=app.constants.TOOL_CATEGORY) location = models.CharField(max_length=1, choices=app.constants.TOOL_LOCATION, blank=False, default='H') models.CharField() shed = models.ForeignKey(Shed, null=True, on_delete=models.SET_NULL) owner = models.ForeignKey(settings.AUTH_USER_MODEL) pickupArrangement = models.TextField(max_length=500) def __str__(self): return self.name def get_all_reservations(self): reservations = self.reservation_set.all() return reservations # returns a query of reservations on the tool based on the reservation_status arg (A, O, AC, R, C, etc.) def get_reservations(self, reservation_status): reservations = self.reservation_set.filter(status=reservation_status) return reservations # Checks if tool has unresolved future reservations that prevent it from moving # Returns true if no unresolved future reservations on it, false otherwise def is_ready_to_move(self): if self.location == "S": return False # Keeps a count of all reservations that might be interfering with moving a tool. blockingReservations = 0 # Checks tool for any active reservations activeReservations = self.get_reservations('AC') blockingReservations = blockingReservations + len(activeReservations) # Checks tool for approved future reservations approvedReservations = self.get_reservations('A') blockingReservations = blockingReservations + len(approvedReservations) # Add additional reservations that might block tool from moving here user = self.owner ownReservations = app.models.Reservation.objects.filter(user=user) ownReservations = ownReservations.filter(status="AC").filter( status="A") blockingReservations = blockingReservations + len(ownReservations) # Check the sum of the lengths of the reservation lists described above. # If sum is zero (no blocking reservations), return ready_to_move = True. Else, return ready_to_move = False if blockingReservations == 0: return True else: return False def get_next_available_date(self): reservations = self.reservation_set.exclude(status='C').exclude(status='CL').exclude(status='O'). \ exclude(status='P').exclude(status='R') blackoutdates = self.blackoutdate_set.all() availableDate = datetime.date.today() addOneDay = datetime.timedelta(days=1) setOfDates = set() for res in reservations: setOfDates = setOfDates.union(res.get_dates_covered()) for bd in blackoutdates: setOfDates = setOfDates.union(bd.get_dates_covered()) unavailableDates = sorted(setOfDates) for date in unavailableDates: while availableDate == date: availableDate = date + addOneDay return availableDate def get_days_until_available(self): today = datetime.date.today() delta = (self.get_next_available_date() - today).days return delta def get_status_label_owner(self): label = "Active" if self.status == "D": label = "Deactivated" else: reservations = self.get_all_reservations() for reservation in reservations: if reservation.status == "RI": label = "Return Initiated" elif reservation.status == "O": label = "Overdue" elif reservation.status == "AC": label = "Lent Out" return label def get_label_type_owner(self): type = "label-success" if self.get_status_label_owner() == "Deactivated": type = "label-danger" if self.get_status_label_owner() == "Return Initiated": type = "label-warning" if self.get_status_label_owner() == "Overdue": type = "label-danger" if self.get_status_label_owner() == "Lent Out": type = "label-warning" return type def get_status_label_borrower(self): label = "Available" daysOnRes = self.get_days_until_available() if daysOnRes > 0: label = self.get_next_available_date() return label def get_label_type_borrower(self): type = "label-warning" if self.get_status_label_borrower() == "Available": type = "label-success" return type def get_init_return_reservation(self): reservations = self.get_reservations('RI') if len(reservations) > 0: return reservations[0] return reservations @property def address(self): if self.location == 'S': return self.shed.address return self.owner.address
class UserProfile(models.Model): " Store profile information about a user " user = models.OneToOneField(User, on_delete=models.CASCADE) realname = models.CharField(verbose_name=_("Real Name"), max_length=150, blank=True) tz = models.CharField(max_length=32, verbose_name=_('Timezone'), default='UTC', choices=location.TimezoneChoices(), blank=False, null=False) avatar = ProcessedImageField(verbose_name=_("Photo Image"), upload_to='avatars', processors=[ResizeToFill(128, 128)], format='PNG', blank=True) city = models.ForeignKey(City, verbose_name=_('Home city'), null=True, blank=True, on_delete=models.CASCADE) web_url = models.URLField(verbose_name=_('Website URL'), blank=True, null=True) twitter = models.CharField(verbose_name=_('Twitter Name'), max_length=32, blank=True, null=True) facebook = models.URLField(verbose_name=_('Facebook URL'), max_length=32, blank=True, null=True) send_notifications = models.BooleanField( verbose_name=_('Send notification emails'), default=True) do_not_track = models.BooleanField(verbose_name=_("Do not track"), default=False) secret_key = models.UUIDField(default=uuid.uuid4, editable=True) categories = models.ManyToManyField('Category', blank=True) topics = models.ManyToManyField('Topic', blank=True) class Meta: ordering = ('user__username', ) def __str__(self): try: if self.realname: return self.realname return "%s" % self.user.username except: return _("Unknown Profile") @property def personal_team(self): teams = Team.objects.filter(access=Team.PERSONAL, owner_profile=self) if teams.count() > 0: return teams[0] else: return Team.objects.create(name=str(self), access=Team.PERSONAL, owner_profile=self, city=self.city) def avatar_url(self): try: if self.avatar is None or self.avatar.name is None or self.avatar.name == '': return settings.STATIC_URL + 'img/avatar_placeholder.png' elif self.avatar.name.startswith('http'): return self.avatar.name else: return self.avatar.url except: return settings.STATIC_URL + 'img/avatar_placeholder.png' def get_timezone(self): try: return pytz.timezone(self.tz) except: return pytz.utc timezone = property(get_timezone) def tolocaltime(self, dt): as_utc = pytz.utc.localize(dt) return as_utc.astimezone(self.timezone) def fromlocaltime(self, dt): local = self.timezone.localize(dt) return local.astimezone(pytz.utc) @property def is_a_team_admin(self): return Member.objects.filter( user=self, role=Member.ADMIN, team__access__in=(Team.PUBLIC, Team.PRIVATE)).count() > 0 @property def administering(self): return [ member.team for member in Member.objects.filter( user=self, role=Member.ADMIN, team__access__in=(Team.PUBLIC, Team.PRIVATE)).order_by('team__name') ] @property def is_a_team_moderator(self): return Member.objects.filter( user=self, role__in=(Member.ADMIN, Member.MODERATOR), team__access__in=(Team.PUBLIC, Team.PRIVATE)).count() > 0 @property def moderating(self): return [ member.team for member in Member.objects.filter( user=self, role__in=(Member.ADMIN, Member.MODERATOR), team__access__in=(Team.PUBLIC, Team.PRIVATE)).order_by('team__name') ] def can_create_event(self, team): try: if self.user.is_superuser: return True except: return False if not self.user_id: return False if team.owner_profile == self: return True if self in team.moderators: return True return False def can_edit_series(self, series): try: if self.user.is_superuser: return True except: return False if series.created_by == self: return True if series.team.owner_profile == self: return True if self in series.team.moderators: return True return False def can_edit_event(self, event): try: if self.user.is_superuser: return True except: return False if event.created_by == self: return True if event.team.owner_profile == self: return True if self in event.team.moderators: return True return False def can_edit_org(self, org): try: if self.user.is_superuser: return True except: return False if not self.user_id: return False if org.owner_profile == self: return True return False def can_create_common_event(self, org): try: if self.user.is_superuser: return True except: return False if not self.user_id: return False if org.owner_profile == self: return True return False def can_edit_team(self, team): try: if self.user.is_superuser: return True except: return False if team.owner_profile == self: return True if self in team.administrators: return True return False
class CustomUser(AbstractUser): profile_picture = ProcessedImageField(default='default-user.png', processors=[ResizeToFill(30, 30)], format='PNG')
class User(AbstractBaseUser, PermissionsMixin): # Personal Info email = models.EmailField(unique=True) full_name = models.CharField('Nome Completo', max_length=255) username = models.SlugField(max_length=30, null=True, blank=True) picture = ProcessedImageField(null=True, blank=True, format='JPEG', options={'quality': 80}, processors=[ResizeToFill(256, 256)], upload_to=user_picture_upload_to) picture_medium = ImageSpecField(format='JPEG', options={'quality': 80}, processors=[ResizeToFill(128, 128)], source='picture') picture_small = ImageSpecField(format='JPEG', options={'quality': 80}, processors=[ResizeToFill(50, 50)], source='picture') # Professional Info job_title = models.CharField(max_length=80, null=True, blank=True) bio = models.TextField(null=True, blank=True) # Status date_joined = models.DateTimeField(auto_now_add=True) date_updated = models.DateTimeField(auto_now=True) is_active = models.BooleanField(editable=False, default=True) is_staff = models.BooleanField(editable=False, default=False) # Notifications email_newsletter = models.BooleanField(default=True) # Verbose names email.verbose_name = 'e-mail' full_name.verbose_name = 'nome completo' username.verbose_name = 'nome de usuário' picture.verbose_name = 'foto do usuário' job_title.verbose_name = 'profissão' bio.verbose_name = 'biografia' USERNAME_FIELD = 'email' REQUIRED_FIELDS = ('full_name', ) objects = UserManager() class Meta: verbose_name = 'usuário' def get_short_name(self): return self.full_name.split()[0] if self.full_name else '' def get_full_name(self): return self.full_name def send_welcome_email(self): send_template_email(subject='Bem vindo!', to=self.email, template_name='emails/welcome.html', context={'user': self})
class Member(BaseModel): """ 科研队伍 """ MEMBER_TYPE = ( ('teacher', '导师'), ('student', '学生'), ) GENDER_CHOICES = (("male", u"男"), ("female", u"女")) name = models.CharField('名称', help_text='名称', max_length=128, null=True, blank=True) birthday = models.DateField("出生年月", help_text="出生年月", null=True, blank=True) age = models.IntegerField('年龄', help_text="年龄", null=True, blank=True) gender = models.CharField('性别', help_text="性别", max_length=6, choices=GENDER_CHOICES, default="male") phone = models.CharField('电话', help_text="电话", null=True, blank=True, max_length=11) email = models.EmailField('邮箱', help_text="邮箱", max_length=100, null=True, blank=True) member_type = models.CharField("成员类型", help_text="成员类型", max_length=16, choices=MEMBER_TYPE, default=MEMBER_TYPE[1]) # 一对多 category = models.ForeignKey(Classification, verbose_name='成员分类', on_delete=models.CASCADE) member_title = models.CharField('成员头衔', help_text='成员头衔', max_length=128, null=True, blank=True) avatar = ProcessedImageField(verbose_name="头像", help_text='头像', upload_to=user_avatar_path, default='avatar/default.jpg', processors=[ResizeToFill(120, 120)], format='JPEG', options={'quality': 60}, null=True, blank=True) introduction = models.TextField('介绍', help_text='介绍', null=True, blank=True) # member_id = models.AutoField('索引', help_text='索引', primary_key=True) member_id = models.IntegerField('索引', help_text='索引', default=0) class Meta: verbose_name = "科研队伍" verbose_name_plural = verbose_name ordering = ['-create_time', 'name'] def __str__(self): return self.name
class Especialista(TimeStampedModel): def firma_upload_to(instance, filename): nombre_especialista = instance.full_name nro_random = random.randint(1111, 9999) return "especialistas/firmas/%s%s.%s" % ( nombre_especialista, nro_random, filename.split('.')[1]) CHOICES_TIPO_DOCUMENTO = ( ('CC', 'Cédula Ciudadanía'), ('CE', 'Cédula Extrangería'), ('PS', 'Pasaporte'), ('TI', 'Tarjeta Identidad'), ) CHOICES_SEXO = (('F', 'Femenino'), ('M', 'Masculino')) user = models.OneToOneField(User, related_name='especialista', on_delete=models.CASCADE) tipo_documento = models.CharField(max_length=2, choices=CHOICES_TIPO_DOCUMENTO, default='CC') nro_identificacion = models.CharField(max_length=30, unique=True) nombre = models.CharField(max_length=60) nombre_segundo = models.CharField(max_length=60, null=True, blank=True) apellido = models.CharField(max_length=60) apellido_segundo = models.CharField(max_length=60, null=True, blank=True) fecha_nacimiento = models.DateTimeField() genero = models.CharField(choices=CHOICES_SEXO, default='F', max_length=20) grupo_sanguineo = models.CharField(max_length=60, null=True, blank=True) especialidad = models.ForeignKey(Especialidad, on_delete=models.PROTECT, verbose_name='Especialidad', null=True, blank=True) universidad = models.CharField(max_length=100, blank=True, null=True) registro_profesional = models.CharField(max_length=100, null=True, blank=True) firma = ProcessedImageField( processors=[ResizeToFit(400, 300), ResizeCanvas(400, 300)], format='PNG', options={'quality': 100}, null=True, blank=True, upload_to=firma_upload_to) class Meta: permissions = ( ('list_especialista', 'Can list especialistas'), ('detail_especialista', 'Can detail especialista'), ) @staticmethod def existe_documento(tipo_documento: str, nro_identificacion: str) -> bool: return Especialista.objects.filter( tipo_documento=tipo_documento, nro_identificacion=nro_identificacion).exists() @property def full_name(self): nombre_segundo = '' if self.nombre_segundo: nombre_segundo = ' %s' % (self.nombre_segundo) apellido_segundo = '' if self.apellido_segundo: apellido_segundo = ' %s' % (self.apellido_segundo) return '%s%s %s%s' % (self.nombre, nombre_segundo, self.apellido, apellido_segundo) def __str__(self): return self.full_name
class User(AbstractUser): logo = ProcessedImageField( upload_to="userlogos/%Y/%m/%d", processors=[ResizeToFill(200, 200)], default="userlogos/user.jpg", format="JPEG", options={"quality": 75}, blank=True, ) description = models.TextField("About me", blank=True) name = models.CharField("full name", max_length=250, db_index=True) date_added = models.DateTimeField("date added", default=timezone.now, db_index=True) is_featured = models.BooleanField("Is featured", default=False, db_index=True) title = models.CharField("Title", max_length=250, blank=True) advancedUser = models.BooleanField("advanced user", default=False, db_index=True) media_count = models.IntegerField(default=0) # save number of videos notification_on_comments = models.BooleanField( "Whether you will receive email notifications for comments added to your content", default=True, ) location = models.CharField("Location", max_length=250, blank=True) is_editor = models.BooleanField("MediaCMS Editor", default=False, db_index=True) is_manager = models.BooleanField("MediaCMS Manager", default=False, db_index=True) allow_contact = models.BooleanField( "Whether allow contact will be shown on profile page", default=False) class Meta: ordering = ["-date_added", "name"] indexes = [models.Index(fields=["-date_added", "name"])] def update_user_media(self): self.media_count = Media.objects.filter(listable=True, user=self).count() self.save(update_fields=["media_count"]) return True def thumbnail_url(self): if self.logo: return helpers.url_from_path(self.logo.path) return None def banner_thumbnail_url(self): c = self.channels.filter().order_by("add_date").first() if c: return helpers.url_from_path(c.banner_logo.path) return None @property def email_is_verified(self): if self.emailaddress_set.first(): if self.emailaddress_set.first().verified: return True return False def get_absolute_url(self, api=False): if api: return reverse("api_get_user", kwargs={"username": self.username}) else: return reverse("get_user", kwargs={"username": self.username}) def edit_url(self): return reverse("edit_user", kwargs={"username": self.username}) def default_channel_edit_url(self): c = self.channels.filter().order_by("add_date").first() if c: return reverse("edit_channel", kwargs={"friendly_token": c.friendly_token}) return None @property def playlists_info(self): ret = [] for playlist in self.playlists.all(): c = {} c["title"] = playlist.title c["description"] = playlist.description c["media_count"] = playlist.media_count c["add_date"] = playlist.add_date c["url"] = playlist.get_absolute_url() ret.append(c) return ret @property def media_info(self): ret = {} results = [] ret["results"] = results ret["user_media"] = "/api/v1/media?author={0}".format(self.username) return ret def save(self, *args, **kwargs): strip_text_items = ["name", "description", "title"] for item in strip_text_items: setattr(self, item, strip_tags(getattr(self, item, None))) super(User, self).save(*args, **kwargs)
class InstaUser(AbstractUser): profile_pic = ProcessedImageField(upload_to='static/images/profiles', format='JPEG', options={'quality': 100}, blank=True)
class Child_detail(caching.base.CachingMixin, models.Model): def save(self): if not self.unique_id_no: self.unique_id_no = (self.school.school_code * 100000) + (self.school.student_id_count + 1) super(Child_detail, self).save() def validate_image(fieldfile_obj): filesize = fieldfile_obj.file.size kb_limit = 50 Kilobyte_limit = 1024 * 50 if filesize > Kilobyte_limit: raise ValidationError("Max file size is %sKB" % str(kb_limit)) def get_path(instance, filename): import random import string random = ''.join([ random.choice(string.ascii_letters + string.digits) for n in xrange(32) ]) extension = filename.split('.')[-1] a = instance.block.block_name.replace(" ", ".") a.replace("(", '_') a.replace(")", '_') try: child = Child_detail.objects.get( unique_id_no=instance.unique_id_no) path = django_settings.MEDIA_ROOT + "/" + str(child.photograph) os.remove(path) except: pass dir = "images/child_pics/%s/%s" % (a, instance.school.school_code) name = str(instance.unique_id_no) + "_" + random return "%s/%s.%s" % (dir, name, extension) name = models.CharField(default='', max_length=200) name_tamil = models.CharField(default='', max_length=200, blank=True, null=True) aadhaar_id = models.CharField(max_length=3) aadhaar_eid_number = models.CharField(max_length=50, blank=True, null=True) aadhaar_uid_number = models.BigIntegerField(blank=True, null=True) photograph = ProcessedImageField(upload_to=get_path, processors=[ResizeToFill(200, 200)], format='JPEG', options={'quality': 60}, blank=True, null=True, validators=[validate_image]) photo = ProcessedImageField( upload_to=get_path, processors=[ResizeToFill(125, 125)], format='JPEG', options={'quality': 60}, blank=True, null=True, ) gender = models.CharField(max_length=15) dob = models.DateField(default='1990-01-01') religion = models.ForeignKey(Religion, blank=True, null=True) community = ChainedForeignKey(Community, chained_field='religion', chained_model_field='religion', auto_choose=True, blank=True, null=True) community_certificate = models.CharField(max_length=3, blank=True, null=True) community_certificate_no = models.CharField(max_length=200, blank=True, null=True) community_certificate_date = models.DateField(blank=True, null=True, default='1990-01-01') nativity_certificate = models.CharField(max_length=3, blank=True, null=True) mothertounge = models.ForeignKey(Language) phone_number = BigIntegerField(default=0, blank=True, null=True) email = models.CharField(max_length=100, blank=True, null=True) child_differently_abled = models.CharField(max_length=3) differently_abled = models.CharField(max_length=30, blank=True, null=True) da_id_no = models.CharField(max_length=20, blank=True, null=True) sci_practical = models.CharField(choices=sp_choice, max_length=30, blank=True, null=True) lang_exemption = models.CharField(choices=le_choice, max_length=30, blank=True, null=True) lang_exemption1 = models.CharField(choices=le_choice, max_length=30, blank=True, null=True) child_admitted_under_reservation = models.CharField(max_length=3, blank=True, null=True) weaker_section = models.CharField(max_length=3, blank=True, null=True) weaker_section_income_certificate_no = models.CharField(max_length=200, blank=True, null=True) child_disadvantaged_group = models.CharField(max_length=3, blank=True, null=True) disadvantaged_group = models.CharField(max_length=1000, blank=True, null=True) subcaste = ChainedForeignKey(Sub_Castes, chained_field='community', chained_model_field='community', auto_choose=True, blank=True, null=True) nationality = models.ForeignKey(Nationality) child_status = models.CharField(max_length=200, blank=True, null=True) house_address = models.CharField(default='', max_length=1000, blank=True, null=True) street_name = models.CharField(default='', max_length=1000, blank=True, null=True) area_village = models.CharField(default='', max_length=1000, blank=True, null=True) city_district = models.CharField(default='', max_length=1000, blank=True, null=True) native_district = models.CharField(max_length=50) pin_code = models.PositiveIntegerField(default=6, blank=True, null=True) blood_group = models.CharField(max_length=10, blank=True, null=True) height = models.PositiveIntegerField(max_length=3, default=0, blank=True, null=True) weight = models.PositiveIntegerField(default=0, blank=True, null=True) mother_name = models.CharField(default='', max_length=100, blank=True, null=True) mother_occupation = models.CharField(max_length=50, blank=True, null=True) father_name = models.CharField(default='', max_length=100, blank=True, null=True) father_occupation = models.CharField(max_length=50, blank=True, null=True) parent_income = models.PositiveIntegerField(default=0, blank=True, null=True) guardian_name = models.CharField(default='', max_length=100, blank=True, null=True) class_studying = models.ForeignKey(Class_Studying) class_section = models.CharField(max_length=30) group_code = models.ForeignKey(Group_code, blank=True, null=True) grpcode_language1 = models.CharField(choices=gcl_choice, max_length=3, blank=True, null=True) grpcode_language2 = models.CharField(choices=gcl_choice, max_length=3, blank=True, null=True) grpcode_language3 = models.CharField(choices=gcl_choice, max_length=3, blank=True, null=True) grpcode_language4 = models.CharField(choices=gcl_choice, max_length=3, blank=True, null=True) first_language = models.CharField(choices=fl_choice, max_length=30, default='', blank=True, null=True) optional_language = models.CharField(choices=ol_choice, max_length=30, default='', blank=True, null=True) attendance_status = models.CharField(max_length=30, blank=True, null=True) sport_participation = models.CharField(max_length=20, blank=True, null=True) laptop_issued = models.CharField(max_length=3, blank=True, null=True) laptop_slno = models.CharField(max_length=200, blank=True, null=True) education_medium = models.ForeignKey(Education_medium) state = models.ForeignKey(State) district = models.ForeignKey(District) block = models.ForeignKey(Block) unique_id_no = models.BigIntegerField(blank=True, null=True) school = models.ForeignKey(School) staff_id = models.CharField(max_length=30) student_admitted_section = models.CharField(max_length=100, blank=True, null=True) school_admission_no = models.CharField(max_length=100) bank = models.ForeignKey(Bank, blank=True, null=True) bank_branch = models.CharField(default='', max_length=200, blank=True, null=True) bank_account_no = models.CharField(default='', max_length=30, blank=True, null=True) bank_ifsc_code = models.CharField(max_length=50, default='', blank=True, null=True) sports_player = models.CharField(max_length=3) sports_name = models.CharField(max_length=1000, blank=True, null=True) # govt_schemes_status = models.CharField(max_length=5) schemes = models.CharField(max_length=1000, blank=True, null=True) academic_year = models.ForeignKey(Academic_Year) scholarship_from_other_source = models.CharField(max_length=3) scholarship_details = models.CharField(max_length=1000, blank=True, null=True) scholarship_other_details = models.CharField(max_length=1000, blank=True, null=True) bus_pass = models.CharField(max_length=3) bus_from_route = models.CharField(max_length=50, blank=True, null=True) bus_to_route = models.CharField(max_length=50, blank=True, null=True) bus_route_no = models.CharField(max_length=5, blank=True, null=True) transfer_flag = models.PositiveIntegerField(default=0, blank=True, null=True) transfer_date = models.DateField(blank=True, null=True) nutritious_meal_flag = models.CharField(default='', max_length=5, blank=True, null=True) modification_flag = models.PositiveIntegerField(default=0, blank=True, null=True) verification_flag = models.PositiveIntegerField(default=0, blank=True, null=True) created_date = models.DateTimeField(auto_now_add=True, editable=False) modified_date = models.DateTimeField(auto_now=True) # thamarai added two fields schl_cat_10 = models.IntegerField(blank=True, null=True) schl_cat_12 = models.IntegerField(blank=True, null=True) objects = caching.base.CachingManager() # history = HistoricalRecords() def __unicode__(self): return u'%s %s %s %s' % (self.unique_id_no, self.name, self.staff_id, self.verification_flag)
class Case(models.Model): STATUS_CHOICES = ( ('결제 대기 중', '결제 대기 중'), ('출원 준비 중', '출원 준비 중'), ('심사 중', '심사 중'), ('출원공고', '출원공고'), ('거절 대응 중', '거절 대응 중'), ('등록 결정', '등록 결정'), ('등록 완료', '등록 완료'), ('갱신 대상', '갱신 대상'), ) trademark_title = models.CharField(max_length=80, null=True, blank=True) file = ProcessedImageField(processors=[Transpose()], format='JPEG', options={'quality': 50}, null=True, blank=True) # 주인이 사라졌을 때, 종속되어 있는 아이들을 어떻게 할것인가? 를 지정해 줘야 하는듯, on_delete=models.PROTECT를 넣어서 해결 owner = models.ForeignKey(user_models.User, null=True, on_delete=models.PROTECT) # examiner 관한 사항 추가 examiner = models.ForeignKey(examiner_models.Examiner, null=True, on_delete=models.PROTECT) import도 역시 해야 함. # payment 관한 사항 추가 payment = models.ForeignKey(payment_models.Payment, null=True, on_delete=models.PROTECT) import도 역시 해야 함. # 여러 사건이 하나의 결제로 이루어질 경우, 각 사건이 하나의 결제를 참조(포인팅)할 수 있다. request_date = models.DateField(auto_now_add=True) payment_date = models.DateField(null=True, blank=True) filed_date = models.DateField(null=True, blank=True) application_number = models.CharField(max_length=80, null=True, blank=True) identification_number = models.CharField(max_length=80, null=True, blank=True) publication_number = models.CharField(max_length=80, blank=True, null=True) publication_date = models.DateField(null=True, blank=True) registration_number = models.CharField(max_length=80, blank=True, null=True) registration_date = models.DateField(null=True, blank=True) products = models.TextField(blank=True, null=True) designatedArray = models.TextField(blank=True, null=True) applicantArray = models.TextField(blank=True, null=True) paymentArray = models.TextField(blank=True, null=True) descriptions = models.TextField(blank=True, null=True) progress_status = models.CharField(max_length=80, choices=STATUS_CHOICES, blank=True, null=True) exam_result_date = models.DateField(null=True, blank=True) expected_date = models.DateField(null=True, blank=True) examiner_name = models.CharField(max_length=80, blank=True, null=True) examiner_phone = models.CharField(max_length=80, blank=True, null=True) examiner_team = models.CharField(max_length=80, blank=True, null=True) waiting_order = models.PositiveSmallIntegerField(blank=True, null=True) waiting_total = models.PositiveSmallIntegerField(blank=True, null=True) def __str__(self): return '상표명: {} - 출원인: {}'.format(self.trademark_title, self.owner.username)
class UserProfile(models.Model): " Store profile information about a user " user = models.OneToOneField(User, on_delete=models.CASCADE) realname = models.CharField(verbose_name=_("Real Name"), max_length=150, blank=True) tz = models.CharField( max_length=32, verbose_name=_("Timezone"), default="UTC", choices=location.TimezoneChoices(), blank=False, null=False, ) avatar = ProcessedImageField( verbose_name=_("Photo Image"), upload_to="avatars", processors=[ResizeToFill(128, 128)], format="PNG", blank=True, ) city = models.ForeignKey( City, verbose_name=_("Home city"), null=True, blank=True, on_delete=models.CASCADE, ) web_url = models.URLField(verbose_name=_("Website URL"), blank=True, null=True) twitter = models.CharField( verbose_name=_("Twitter Name"), max_length=32, blank=True, null=True ) facebook = models.URLField( verbose_name=_("Facebook URL"), max_length=32, blank=True, null=True ) send_notifications = models.BooleanField( verbose_name=_("Send notification emails"), default=True ) do_not_track = models.BooleanField(verbose_name=_("Do not track"), default=False) secret_key = models.UUIDField(default=uuid.uuid4, editable=True) categories = models.ManyToManyField("Category", blank=True) topics = models.ManyToManyField("Topic", blank=True) class Meta: ordering = ("user__username",) def __str__(self): try: if self.realname: return self.realname return "%s" % self.user.username except: return _("Unknown Profile") @property def personal_team(self): teams = Team.objects.filter(access=Team.PERSONAL, owner_profile=self) if teams.count() > 0: return teams[0] else: new_slug = slugify(str(self)) slug_matches = list(Team.objects.filter(slug=new_slug)) if len(slug_matches) == 0 or ( len(slug_matches) == 1 and slug_matches[0].owner_profile.id == self.id ): team_slug = new_slug else: team_slug = "%s-u%s" % (new_slug, self.id) return Team.objects.create( name=str(self), slug=team_slug, access=Team.PERSONAL, owner_profile=self, city=self.city, ) def avatar_url(self): try: if ( self.avatar is None or self.avatar.name is None or self.avatar.name == "" ): return settings.STATIC_URL + "img/avatar_placeholder.png" elif self.avatar.name.startswith("http"): return self.avatar.name else: return self.avatar.url except: return settings.STATIC_URL + "img/avatar_placeholder.png" def get_timezone(self): try: return pytz.timezone(self.tz) except: return pytz.utc timezone = property(get_timezone) def tolocaltime(self, dt): as_utc = pytz.utc.localize(dt) return as_utc.astimezone(self.timezone) def fromlocaltime(self, dt): local = self.timezone.localize(dt) return local.astimezone(pytz.utc) @property def is_a_team_admin(self): return ( Member.objects.filter( user=self, role=Member.ADMIN, team__access__in=(Team.PUBLIC, Team.PRIVATE), ).count() > 0 ) @property def administering(self): return [ member.team for member in Member.objects.filter( user=self, role=Member.ADMIN, team__access__in=(Team.PUBLIC, Team.PRIVATE), ).order_by("team__name") ] @property def is_a_team_moderator(self): return ( Member.objects.filter( user=self, role__in=(Member.ADMIN, Member.MODERATOR), team__access__in=(Team.PUBLIC, Team.PRIVATE), ).count() > 0 ) @property def moderating(self): return [ member.team for member in Member.objects.filter( user=self, role__in=(Member.ADMIN, Member.MODERATOR), team__access__in=(Team.PUBLIC, Team.PRIVATE), ).order_by("team__name") ] def can_create_event(self, team): try: if self.user.is_superuser: return True except: return False if not self.user_id: return False if team.owner_profile == self: return True if self in team.moderators: return True return False def can_edit_series(self, series): try: if self.user.is_superuser: return True except: return False if series.created_by == self: return True if series.team.owner_profile == self: return True if self in series.team.moderators: return True return False def can_edit_event(self, event): try: if self.user.is_superuser: return True except: return False if event.created_by == self: return True if event.team.owner_profile == self: return True if self in event.team.moderators: return True return False def can_edit_org(self, org): try: if self.user.is_superuser: return True except: return False if not self.user_id: return False if org.owner_profile == self: return True return False def can_create_common_event(self, org): try: if self.user.is_superuser: return True except: return False if not self.user_id: return False if org.owner_profile == self: return True return False def can_edit_team(self, team): try: if self.user.is_superuser: return True except: return False if team.owner_profile == self: return True if self in team.administrators: return True return False def is_in_team(self, team): if self.can_edit_team(team): return True return Member.objects.filter(team=team, user=self).count() > 0
class Person(models.Model): """A Person reflects one single real Person, there shall be no two person objects for the same Person Persons CAN be linked to users of the application, meaning that the person is a User of this application """ SEX = [ ["m"] * 2, ["f"] * 2, ] objects = PersonEligibility.as_manager() # personal information firstname = models.CharField(max_length=200) lastname = models.CharField(max_length=200) sex = models.CharField(max_length=1, choices=SEX) birthdate = ( models.DateField() ) # TODO: validator to check that date is not in the future # specify image directory # Memberships club_memberships = models.ManyToManyField("Club", through="PersonToClubMembership") team_memberships = models.ManyToManyField("Team", through="PersonToTeamMembership") association_memberships = models.ManyToManyField( "Association", through="PersonToAssociationMembership" ) # other relationships roster_relationships = models.ManyToManyField( "Roster", through="PersonToRosterRelationship" ) # todo this should be models.oneTooneField but the faking factory is not capable atm to build unique relationships between person and user user = models.ForeignKey(User, on_delete=models.CASCADE) image = ProcessedImageField( upload_to="images/persons/", processors=[ResizeToFit(width=500, height=500)], format="JPEG", options={"quality": 80}, blank=True, null=True, ) face = ImageSpecField( source="image", processors=[DetectFaceAndResizeToFit(width=70, height=70)], format="JPEG", options={"quality": 80}, ) def image_45p_tag(self): if self.face and hasattr(self.face, "url"): return mark_safe('<img src="%s" style="height:70px;" />' % self.face.url) else: return "-" image_45p_tag.short_description = "image" def image_500p_tag(self): if self.image and hasattr(self.image, "url"): return mark_safe( '<img src="%s" style="max-width: 500px;" />' % self.image.url ) else: return "-" image_500p_tag.short_description = "image" # elegibility def eligibile_u17(self) -> bool: return date.today().year - self.birthdate.year <= 17 eligibile_u17.boolean = True eligibile_u17.short_description = "u17" def eligibile_u20(self) -> bool: return date.today().year - self.birthdate.year <= 20 eligibile_u20.boolean = True eligibile_u20.short_description = "u20" def eligibile_u24(self) -> bool: return date.today().year - self.birthdate.year <= 24 eligibile_u24.boolean = True eligibile_u24.short_description = "u24" @property def eligibile_masters(self): return self.birthdate @property def eligibile_grandmasters(self): return self.birthdate @property def eligibile_open(self): return self.birthdate @property def eligibile_women(self): return self.birthdate @property def eligibile_mixed(self): return self.birthdate def get_current_clubmemberships(self) -> models.QuerySet: today = date.today() this_year = date(year=today.year, month=1, day=1) club_memberships = PersonToClubMembership.objects.filter(person=self).filter( Q(valid_until__gte=this_year) | Q(valid_until__isnull=True) ) return club_memberships def eligibile_onlyOneClub(self) -> bool: return self.get_current_clubmemberships().count() < 2 eligibile_onlyOneClub.boolean = True eligibile_onlyOneClub.short_description = "Nur ein Verein" # TODO: #68 #67 refactor into elegibilty framework def eligibile_nationals(self, tournament: str, year=date.today().year) -> bool: current_clubs = Club.objects.filter( persontoclubmembership__in=self.get_current_clubmemberships().all() ) roster = Roster.objects.filter( Q(person=self) & Q(tournament_division__tournament__name__contains=tournament) & Q(tournament_division__tournament__start__year__gte=year) & ~Q(team__club_membership__in=current_clubs) ) return roster.count() < 2 def eligibile_nationals_o(self): return self.eligibile_nationals("ÖSTM OPEN") eligibile_nationals_o.boolean = True eligibile_nationals_o.short_description = "El. ÖSTM O" def eligibile_nationals_w(self): return self.eligibile_nationals("ÖM WOMEN") eligibile_nationals_w.boolean = True eligibile_nationals_w.short_description = "El. ÖSTM W" def eligibile_nationals_mixed(self): return self.eligibile_nationals("ÖSTM MIXED") eligibile_nationals_mixed.boolean = True eligibile_nationals_mixed.short_description = "El. ÖSTM X" def eligibile_nationals_beach(self): return self.eligibile_nationals("BÖSTM") eligibile_nationals_beach.boolean = True eligibile_nationals_beach.short_description = "El. BÖSTM" def __str__(self): return f"{self.firstname} {self.lastname} ({self.birthdate.year})" class Meta: db_table = "pm_Person"
class Post(models.Model): VUE = "VUE" DJANGO = "DJANGO" PYTHON = "PYTHON" OTHER = "OTHER" THEMES = ( (DJANGO, "Django"), (VUE, "Vue"), (PYTHON, "Python"), (OTHER, "Other"), ) label_img = ProcessedImageField( upload_to=path_label_img, default="label_img/images.jpeg", processors=[ResizeToFill(500, 150)], format="JPEG", options={"quality": 100}, blank=True, null=True, ) theme = models.CharField(choices=THEMES, max_length=150) headline = models.CharField(max_length=500) description = models.CharField(max_length=1500, blank=True, null=True) article = HTMLField("Article") author = models.ForeignKey(USER, on_delete=models.CASCADE) created = models.DateTimeField(default=timezone.now) views = models.IntegerField(default=0) likesystem = GenericRelation( "LikeSystem", related_query_name="post" ) # like and dislike objects comments = GenericRelation( "Comment", related_query_name="post" ) # comments class Meta: ordering = ["-id"] verbose_name = "Пост" verbose_name_plural = "Посты" def __str__(self): return self.headline def get_tags(self): tags = Tag.objects.all().filter(post=self) return tags def get_absolute_url(self): from django.urls import reverse return reverse("post_detail", args=[str(self.id)]) def get_created(self): created = pendulum.instance(self.created) created = created.format("DD MMMM YYYY", locale="ru") return created def comment_count(self): comment = Comment.objects.filter( content_type=ContentType.objects.get_for_model(self), object_id=self.id, ) return comment.count()
class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) description = models.CharField(max_length=100, blank=True) follow_set = models.ManyToManyField( 'self', blank=True, through='Relation', symmetrical=False, ) avatar = ProcessedImageField(upload_to='avatars/%Y/%m/%d/', processors=[ResizeToFill(150, 150)], format='JPEG', options={'quality': 60}, default='avatars/default.jpg') slug = models.SlugField(allow_unicode=True, default='') def __str__(self): return self.user.nickname @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: slug = slugify(instance.nickname, allow_unicode=True) Profile.objects.create(user=instance, slug=slug) @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): slug = slugify(instance.nickname, allow_unicode=True) if not instance.profile.slug: instance.profile.slug = slug else: instance.profile.slug = slug instance.profile.save() @property def get_follower(self): return [ i.from_user for i in self.follower_user.all().select_related( 'from_user__user__profile') ] @property def get_following(self): return [ i.to_user for i in self.follow_user.all().select_related( 'to_user__user__profile') ] @property def get_pk_follower(self): return self.follower_user.all().values_list('from_user', flat=True) @property def follower_count(self): return len(self.get_follower) @property def following_count(self): return len(self.get_following) @property def get_joining(self): return [ i.to_club for i in self.join_user.all().select_related('to_club') ] @property def get_joining_title(self): return self.join_user.all().values_list('to_club__title', flat=True) @property def joining_count(self): return len(self.get_joining)
case = models.ForeignKey(case_models.Case, null=True, on_delete=models.PROTECT) owner = models.ForeignKey(user_models.User, null=True, on_delete=models.PROTECT) date_of_file = models.DateField(auto_now_add=True) possibility = models.PositiveSmallIntegerField(blank=True, null=True) attorneyComment = models.TextField(blank=True, null=True) clientGiveup = models.BooleanField(default=False) is_notified = models.BooleanField(default=False) image1 = ProcessedImageField(processors=[Transpose()], format='JPEG', options={'quality': 50}, blank=True, null=True) date_of_image1 = models.DateField(blank=True, null=True) application_number1 = models.CharField(max_length=80, blank=True, null=True) applicant1 = models.CharField(max_length=80, blank=True, null=True) image2 = ProcessedImageField(processors=[Transpose()], format='JPEG', options={'quality': 50}, blank=True, null=True) date_of_image2 = models.DateField(blank=True, null=True) application_number2 = models.CharField(max_length=80, blank=True,
class Profile(models.Model): ''' 该接口更新接受PUT方法 性别字段英文对应汉字为: male:男 female:女 提交的数据要用英文.获取时候api也是英文, 要客户端自己做下转换. ''' GENDER_CHOICES = (('', '未知'), ('male', '男'), ('female', '女')) owner = models.OneToOneField(settings.AUTH_USER_MODEL, unique=True, db_index=True, related_name='profile', on_delete=models.CASCADE) name = models.CharField(verbose_name=_(u'姓名'), blank=True, max_length=100, db_index=True) nick = models.CharField(verbose_name=_(u'昵称'), blank=True, null=True, max_length=100, db_index=True, default='') mobile = models.CharField(verbose_name=_(u'电话号码'), max_length=50, default='') gender = models.CharField(verbose_name=_(u'性别'), max_length=10, choices=GENDER_CHOICES, default=u'male') credit = models.IntegerField(_(u'用户积分'), default='50') avatar = ProcessedImageField(verbose_name=_(u'头像'), upload_to='avatar', processors=[ResizeToFill(320, 320)], format='JPEG', null=True, default='avatar/default.jpg') birthday = models.DateField(_(u'生日'), blank=True, null=True) balance = models.DecimalField(verbose_name=_(u'数字币余额'), max_digits=10, decimal_places=2, default=0.00) expired = models.DateTimeField(verbose_name=_(u'到期时间'), blank=True, null=True) # @property # def qrcode(self, request): # reverse('q', args=[short_url.encode_url(self.pk)], request=request) def __str__(self): return self.name def generate_key(self): return binascii.hexlify(os.urandom(20)).decode() class Meta: verbose_name = _(u'用户信息') verbose_name_plural = _(u'用户信息')
class Post(models.Model): content = models.TextField() imgfile = ProcessedImageField(upload_to='blog/post', format='JPEG', options={'quality': 100})
class User(AbstractUser): uuid = models.UUIDField(default=uuid.uuid4, max_length=255, editable=False, unique=True) username = models.CharField( max_length=255, blank=False, null=False, unique=True, ) email = models.EmailField(unique=True, null=False, blank=False) first_name = None last_name = None birthday = models.DateField(blank=False, null=True) is_email_verified = models.BooleanField(default=False) is_deleted = models.BooleanField(default=False) GENDER = ( ("M", "Male"), ("F", "Female"), ) gender = models.CharField(choices=GENDER, max_length=1, null=True, blank=False) OCCUPATIONS = ( (None, "Select your role"), ("Student", "Student"), ("PhD Student", "PhD Student"), ("Assistant", "Assistant"), ("Researcher", "Researcher"), ("Assistant Professor", "Assistant Professor"), ("Associate Professor", "Associate Professor"), ("Professor", "Professor"), ("Head of Department", "Head of Department"), ("Head of Faculty", "Head of Faculty"), ("Head of Laboratory", "Head of Laboratory"), ("Vice Rector", "Vice Rector"), ("Rector", "Rector"), ("Software Developer", "Software Developer"), ("Engineer", "Engineer"), ("Technician", "Technician"), ("Economist", "Economist"), ("Lawyer", "Lawyer"), ("Instructor", "Instructor"), ("Consultant", "Consultant"), ("Manager", "Manager"), ("Administrator", "Administrator"), ("Analyst", "Analyst"), ("Journalist", "Journalist"), ("Writer", "Writer"), ("Editor", "Editor"), ("Librarian", "Librarian"), ("Vice Director", "Vice Director"), ("Chief Executive Officer", "Chief Executive Officer"), ("Retired", "Retired"), ("Other", "Other"), ) occupation = models.CharField(choices=OCCUPATIONS, max_length=30, null=True) avatar = ProcessedImageField(upload_to=upload_to_user_avatar_directory, blank=False, null=True, format="JPEG")
class ArticlePost(models.Model): """ 文章的 Model """ # 定义文章作者。 author 通过 models.ForeignKey 外键与内建的 User 模型关联在一起 # 参数 on_delete 用于指定数据删除的方式,避免两个关联表的数据不一致。通常设置为 CASCADE 级联删除就可以了 author = models.ForeignKey(User, on_delete=models.CASCADE) # 文章标题图 avatar = ProcessedImageField( upload_to='article/%Y%m%d', processors=[ResizeToFit(400, 300)], format='JPEG', options={'quality': 100}, ) # 文章栏目的 “一对多” 外键 column = models.ForeignKey(ArticleColumn, null=True, blank=True, on_delete=models.CASCADE, related_name='article') # 文章标签 # 采用 Django-taggit 库 tags = TaggableManager(blank=True) # 文章标题。 # models.CharField 为字符串字段,用于保存较短的字符串,比如标题 # CharField 有一个必填参数 max_length,它规定字符的最大长度 title = models.CharField(max_length=100) # 文章正文。 # 保存大量文本使用 TextField body = models.TextField() # 浏览量 total_views = models.PositiveIntegerField(default=0) # 文章点赞数 likes = models.PositiveIntegerField(default=0) # 文章创建时间。 # DateTimeField 为一个日期字段 # 参数 default=timezone.now 指定其在创建数据时将默认写入当前的时间 created = models.DateTimeField(default=timezone.now) # 文章更新时间。 # 参数 auto_now=True 指定每次数据更新时自动写入当前时间 updated = models.DateTimeField(auto_now=True) # 内部类 class Meta 用于给 model 定义元数据 # 元数据:不是一个字段的任何数据 class Meta: # ordering 指定模型返回的数据的排列顺序 # '-created' 表明数据应该以倒序排列 ordering = ('-created', ) # 函数 __str__ 定义当调用对象的 str() 方法时的返回值内容 # 它最常见的就是在Django管理后台中做为对象的显示值。因此应该总是为 __str__ 返回一个友好易读的字符串 def __str__(self): # 将文章标题返回 return self.title # 获取文章地址 def get_absolute_url(self): return reverse('article:article_detail', args=[self.id]) # 保存时处理图片 # def save(self, *args, **kwargs): # # 调用原有的 save() 的功能 # article = super(ArticlePost, self).save(*args, **kwargs) # # # 固定宽度缩放图片大小 # if self.avatar and not kwargs.get('update_fields'): # image = Image.open(self.avatar) # (x, y) = image.size # new_x = 400 # new_y = int(new_x * (y / x)) # resized_image = image.resize((new_x, new_y), Image.ANTIALIAS) # resized_image.save(self.avatar.path) # # return article def was_created_recently(self): # 若文章是 1 分钟内发表的,则返回 True diff = timezone.now() - self.created # if diff.days <= 0 and diff.seconds < 60: if diff.days == 0 and diff.seconds >= 0 and diff.seconds < 60: return True else: return False
class Project(models.Model): """ Модель проекта строительства со статусом """ DEVELOPMENT = 'разработка' EXPERTISE = 'экспертиза' TENDER = 'аукцион' EXECUTING = 'строительство' FINISHING = 'сдача' PAYMENT = 'выплата' DONE = 'завершен' STATUS_CHOICES = ( (DEVELOPMENT, 'разработка'), (EXPERTISE, 'экспертиза'), (TENDER, 'аукцион'), (EXECUTING, 'строительство'), (FINISHING, 'сдача'), (PAYMENT, 'выплата'), (DONE, 'завершен'), ) name = models.CharField(verbose_name='Название проекта', max_length=256, unique=True) slug = models.SlugField(verbose_name='слаг', max_length=128, blank=True) description = models.TextField(verbose_name='описание', blank=True) image = ProcessedImageField(verbose_name='Аватар', upload_to='projects_images/avatars', processors=[ResizeToFill(530, 530)], default='projects_images/avatars/default_bridge.png') # image = models.ImageField(verbose_name='Аватар', upload_to='projects_images/avatars', # default='users/avatar/no_avatar.png', blank=True) status = models.CharField(verbose_name='Статус', max_length=24, choices=STATUS_CHOICES) creation_date = models.DateTimeField(verbose_name='создан', auto_now_add=True, auto_now=False) updated = models.DateTimeField(verbose_name='обновлен', auto_now=True) city = models.CharField(verbose_name='город', max_length=512, blank=True, null=True) address = models.CharField(verbose_name='адрес', max_length=512, blank=True, null=True) coordinate = models.CharField(verbose_name='координаты', max_length=34, null=True, blank=True) map_mark = models.SlugField(verbose_name='id метки на карте', max_length=128, blank=True) is_active = models.BooleanField(verbose_name='активен', default=False) def get_absolute_url(self): return reverse('projects:project', args=[str(self.pk)]) def get_absolute_discuss_url(self): return reverse('projects:project_discuss_items', args=[str(self.id)]) def __str__(self): return f"{self.name} ({self.city})" def get_pictures(self): return self.images.select_related() def get_products(self): return self.solutions.select_related() def get_companies(self): return self.companies.select_related() def get_managers(self): return self.managers.select_related() def get_finished_projects(self): pass def get_comments(self): return self.comments.select_related() class Meta: ordering = ('-updated',) verbose_name = 'Проект' verbose_name_plural = 'Проекты' default_permissions = ('add', 'change', 'delete')
class Solucion(TimeStampedModel): def header_imagen_upload_to(instance, filename): new_filename = get_image_name('Header', filename) return "web/img/solu/%s" % new_filename def imagen_boton_upload_to(instance, filename): new_filename = get_image_name('Boton Solucion', filename) return "web/img/solu/%s" % new_filename nombre = models.CharField(max_length=120, verbose_name=_('Nombre')) nombre_en = models.CharField(max_length=120, verbose_name='Nombre en ingles', default='Nombre en Ingles') icono_class = models.CharField(default='', max_length=100) texto = HTMLField('Texto Soluciones', default='Descripción de esta solución', null=True, blank=True) texto_en = HTMLField('Texto Soluciones Ingles', default='Descripción de esta solución en Ingles', null=True, blank=True) orden = models.PositiveIntegerField(default=0) slug = models.SlugField(null=True, blank=True) header_imagen = ProcessedImageField( processors=[SmartResize(width=2560, height=588, upscale=False)], format='JPEG', options={'quality': 70}, upload_to=header_imagen_upload_to, verbose_name='Imagen Cabezote', null=True, blank=True) def save(self, force_insert=False, force_update=False, using=None, update_fields=None): super().save(force_insert, force_update, using, update_fields) cache = CacheConfiguration.objects.get() cache.soluciones_update = timezone.now() cache.save() def delete(self, using=None, keep_parents=False): cache = CacheConfiguration.objects.get() cache.soluciones_update = timezone.now() cache.save() return super().delete(using, keep_parents) def get_absolute_url(self): if self.slug: return reverse('web_soluciones:solucion_detail_slug', kwargs={"slug": self.slug}) return reverse('web_soluciones:solucion_detail', kwargs={"pk": self.pk}) def __str__(self): return self.nombre class Meta: verbose_name = 'Solución' verbose_name_plural = 'Soluciones'