def test_max_length(self): field = SetTextField(models.CharField(max_length=32), size=3) field.clean({"a", "b", "c"}, None) with pytest.raises(exceptions.ValidationError) as excinfo: field.clean({"a", "b", "c", "d"}, None) assert excinfo.value.messages[0] == "Set contains 4 items, it should contain no more than 3."
def test_makemigrations_with_size(self): field = SetTextField(models.CharField(max_length=5), size=5) statement, imports = MigrationWriter.serialize(field) assert statement == ( "django_mysql.models.SetTextField(models.CharField(max_length=5), " + "size=5)")
class BorderPolicy(models.Model): MANDATORY_CENTRALIZED = 'M' MANDATORY_SELF = 'D' FREE_SELF = 'S' NO_POLICY = 'N' UNKNOWN = 'U' TRUE = "T" FALSE = "F" QUARANTINE_CHOICES = [ (MANDATORY_CENTRALIZED, 'Mandatory and centrailzed '), (MANDATORY_SELF, 'Mandatory self quarantine'), (FREE_SELF, 'Self quarantine advice with no enforcement mechanism'), (NO_POLICY, 'No policy whatsoever'), (UNKNOWN, 'Unknown'), ] STATUS_CHOICES = [(TRUE, 'true'), (FALSE, 'false'), (UNKNOWN, 'unknown')] country = models.ForeignKey(Country, on_delete=models.CASCADE, null=False, blank=False, related_name="policies") quarantine = models.CharField(choices=QUARANTINE_CHOICES, max_length=1, default=UNKNOWN) status = models.CharField(choices=STATUS_CHOICES, max_length=1, default=UNKNOWN) url = models.TextField(null=True, blank=True) exemptions = SetTextField(base_field=models.CharField(max_length=20)) time = models.DateTimeField(auto_now=True)
def test_makemigrations(self): field = SetTextField(models.CharField(max_length=5)) statement, imports = MigrationWriter.serialize(field) assert (statement == "django_mysql.models.SetTextField(" "models.CharField(max_length=5), " "size=None" ")")
class Question(models.Model): text = models.TextField() reference_answer = models.TextField(default=None, blank=True, null=True) keywords_csv = SetTextField( models.CharField(max_length=70, blank=True), ) # keywords_csv = models.TextField() def __str__(self): return self.text
class XMLIssue(models.Model): report = models.ForeignKey(Report, on_delete=models.CASCADE) created_time = models.DateTimeField(auto_now=True) sourcefile = models.TextField() startLine = models.IntegerField() endLine = models.IntegerField() group = models.CharField(max_length=20) code = models.TextField() severity = models.CharField(max_length=10) rule = SetTextField(base_field=models.CharField(max_length=32), )
class CSVIssue(models.Model): report = models.ForeignKey(Report, on_delete=models.CASCADE) created_time = models.DateTimeField(auto_now=False) updated_time = models.DateTimeField(auto_now=False) severity = models.CharField(max_length=10) status = models.CharField(max_length=20) cwe = models.IntegerField(blank=True) rule = SetTextField(base_field=models.CharField(max_length=32), ) tool = models.CharField(max_length=32) location = models.TextField() element = models.CharField(max_length=32) path = models.TextField() line = models.IntegerField()
def test_max_length(self): field = SetTextField(models.CharField(max_length=32), size=3) field.clean({"a", "b", "c"}, None) with pytest.raises(exceptions.ValidationError) as excinfo: field.clean({"a", "b", "c", "d"}, None) assert (excinfo.value.messages[0] == "Set contains 4 items, it should contain no more than 3.")
class Account(AbstractBaseUser): email = models.EmailField(verbose_name="email", max_length=60, unique=True) username = models.CharField(max_length=30, unique=True) address = models.TextField(max_length=100, default='') latitude = models.DecimalField(max_digits=18, decimal_places=15, default=Decimal('0.0')) longitude = models.DecimalField(max_digits=18, decimal_places=15, default=Decimal('0.0')) unwanted_dishes = SetTextField(base_field=models.CharField(max_length=50), blank=True, null=True) # mandatory fields from abstractBaseUser date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True) last_login = models.DateTimeField(verbose_name='last login', auto_now=True) is_admin = models.BooleanField(default=False) is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) is_superuser = models.BooleanField(default=False) USERNAME_FIELD = 'username' REQUIRED_FIELDS = ['email', 'address'] objects = MyAccountManager() def __str__(self): return self.email # For checking permissions. to keep it simple all admin have ALL permissons def has_perm(self, perm, obj=None): return self.is_admin # Does this user have permission to view this app? (ALWAYS YES FOR SIMPLICITY) def has_module_perms(self, app_label): return True
def test_model_field_formfield_size(self): model_field = SetTextField(models.IntegerField(), size=400) form_field = model_field.formfield() assert isinstance(form_field, SimpleSetField) assert form_field.max_length == 400
class UserProfileBase(models.Model): class Meta: verbose_name = '用户信息数据表' verbose_name_plural = '用户信息数据表' # "改造用户身份认证所需表结构" fromUser = models.OneToOneField(User) nickName = models.CharField(max_length=30) # 微信昵称 openId = models.CharField(max_length=50) # Openid Sex = models.IntegerField(default=True) # 微信标识的性别 userName = models.CharField(u"用户名", max_length=30) # 用户真实名称,注册时输入的 country = models.CharField(max_length=30) # 国家 province = models.CharField(max_length=30) # 省份 city = models.CharField(max_length=30) # 城市 phonenum = models.CharField(u"电话号码", max_length=20) # 电话 avatarAddr = models.URLField() # 头像 Role = models.IntegerField(default=True) # 身份 Location_lati = models.FloatField(null=True) # 定位 Location_longi = models.FloatField(null=True) # 定位 Score = models.IntegerField(default=5) # 评分 ScoreCount = models.IntegerField(default=True) # 评价人数 Jobs = SetTextField( base_field=models.CharField(max_length=32), ) # 工种类型 online = models.BooleanField(u"是否在线",default=False) # 是否在线 createTime = models.DateTimeField(u"创建时间", auto_now_add=True) # 注册时间 last_login = models.DateField(default=None) # 最后访问时间 publishTime = models.CharField(max_length=20, null=True) last_login2 = models.CharField(max_length=20, null=True) def login_time_str(self): if self.last_login2: xx = datetime.datetime.fromtimestamp(float(self.last_login2)) strtime = xx.strftime('%Y-%m-%d %H:%M:%S') else: xx = datetime.datetime.fromtimestamp(1529127035.18) strtime = xx.strftime('%Y-%m-%d %H:%M:%S') return strtime def pub_time_str(self): if self.publishTime: xx = datetime.datetime.fromtimestamp(float(self.publishTime)) strtime = xx.strftime('%Y-%m-%d %H:%M:%S') else: strtime = "----" return strtime def role_for_admin(self): if self.Role == 1: return u"工人" else: return u"老板" def Jobs_for_admin(self): job_string = "" if self.Jobs: for job in self.Jobs: job_string += job job_string += ", " return job_string login_time_str.short_description = "上次登录时间" pub_time_str.short_description = "发布时间" role_for_admin.short_description = "用户身份" Jobs_for_admin.short_description = "用户工种" Jobs_for_a = property(Jobs_for_admin) role_for_a = property(role_for_admin) login_time_p = property(login_time_str) pub_time_p = property(pub_time_str)
class ControlConfigure(models.Model): project = models.ForeignKey(Project, on_delete=models.CASCADE) control = models.ForeignKey(Control, on_delete=models.CASCADE) keywords = SetTextField(base_field=models.CharField(max_length=32), )
def test_char(self): field = SetTextField(models.CharField(max_length=5), max_length=32) assert field.description == "Set of String (up to %(max_length)s)"
def test_model_field_formfield(self): model_field = SetTextField(models.CharField(max_length=27)) form_field = model_field.formfield() assert isinstance(form_field, SimpleSetField) assert isinstance(form_field.base_field, forms.CharField) assert form_field.base_field.max_length == 27
def test_deconstruct(self): field = SetTextField(models.IntegerField(), max_length=32) name, path, args, kwargs = field.deconstruct() new = SetTextField(*args, **kwargs) assert new.base_field.__class__ == field.base_field.__class__
def test_deconstruct_args(self): field = SetTextField(models.CharField(max_length=5), max_length=32) name, path, args, kwargs = field.deconstruct() new = SetTextField(*args, **kwargs) assert new.base_field.max_length == field.base_field.max_length
class InvalidSetTextModel1(TemporaryModel): field = SetTextField(models.CharField())
def test_deconstruct_with_size(self): field = SetTextField(models.IntegerField(), size=3, max_length=32) name, path, args, kwargs = field.deconstruct() new = SetTextField(*args, **kwargs) assert new.size == field.size
class InvalidSetTextModel2(TemporaryModel): field = SetTextField( models.ForeignKey("testapp.Author", on_delete=models.CASCADE))
class InvalidSetTextModel(TemporaryModel): field = SetTextField(models.ForeignKey('testapp.Author'))
class Invalid(models.Model): field = SetTextField(models.CharField())
class AbstractPost(DatedModel): """ Represents a forum post. A forum post is always linked to a topic. """ topic = models.ForeignKey('forum_conversation.Topic', related_name='posts', on_delete=models.CASCADE, verbose_name=_('Topic')) poster = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='posts', blank=True, null=True, on_delete=models.CASCADE, verbose_name=_('Poster')) poster_ip = models.GenericIPAddressField( verbose_name=_('Poster IP address'), blank=True, null=True, default='2002::0') anonymous_key = models.CharField( max_length=100, verbose_name=_('Anonymous user forum key'), blank=True, null=True) # Each post can have its own subject. The subject of the thread corresponds to the # one associated with the first post subject = models.CharField(verbose_name=_('Subject'), max_length=255) # Content content = MarkupTextField(verbose_name=_('Content'), validators=[ validators.NullableMaxLengthValidator( machina_settings.POST_CONTENT_MAX_LENGTH) ]) tokens = SetTextField(base_field=models.CharField(max_length=255), null=True) # Username: if the user creating a topic post is not authenticated, he must enter a username username = models.CharField(verbose_name=_('Username'), max_length=155, blank=True, null=True) # A post can be approved before publishing ; defaults to True approved = models.BooleanField(verbose_name=_('Approved'), default=True, db_index=True) # The user can choose if they want to display their signature with the content of the post enable_signature = models.BooleanField( verbose_name=_('Attach a signature'), default=True, db_index=True) # A post can be edited for several reason (eg. moderation) ; the reason why it has been # updated can be specified update_reason = models.CharField(max_length=255, verbose_name=_('Update reason'), blank=True, null=True) # Tracking data updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, editable=False, blank=True, null=True, on_delete=models.SET_NULL, verbose_name=_('Lastly updated by')) updates_count = models.PositiveIntegerField( verbose_name=_('Updates count'), editable=False, blank=True, default=0) # Many users can upvote to this topic upvoters = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='post_upvoters', blank=True, verbose_name=_('Upvoters')) vote_count = models.PositiveIntegerField(verbose_name=_('Vote count'), editable=False, blank=True, default=0) # Many users can flag to this topic flaggers = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='post_flaggers', blank=True, verbose_name=_('Flaggers')) flag_count = models.PositiveIntegerField(verbose_name=_('Flag count'), editable=False, blank=True, default=0) objects = models.Manager() approved_objects = ApprovedManager() class Meta: abstract = True app_label = 'forum_conversation' ordering = [ 'created', ] get_latest_by = 'created' verbose_name = _('Post') verbose_name_plural = _('Posts') def __str__(self): return self.subject @property def is_topic_head(self): """ Returns True if the post is the first post of the topic. """ return self.topic.first_post.id == self.id if self.topic.first_post else False @property def is_topic_tail(self): """ Returns True if the post is the last post of the topic. """ return self.topic.last_post.id == self.id if self.topic.last_post else False @property def is_alone(self): """ Returns True if the post is the only single post of the topic. """ return self.topic.posts.count() == 1 @property def position(self): """ Returns an integer corresponding to the position of the post in the topic. """ position = self.topic.posts.filter( Q(created__lt=self.created) | Q(id=self.id)).count() return position def has_upvoter(self, user): """ Returns True if the given user is a upvoter of a post """ if not hasattr(self, '_upvoters'): self._upvoters = list(self.upvoters.all()) return user in self._upvoters def has_flagger(self, user): """ Returns True if the given user is a flagger of a post """ if not hasattr(self, '_flaggers'): self._flaggers = list(self.flaggers.all()) return user in self._flaggers def clean(self): super(AbstractPost, self).clean() # At least a poster (user) or a session key must be associated with # the post. if self.poster is None and self.anonymous_key is None: raise ValidationError( _('A user id or an anonymous key must be associated with a post.' )) if self.poster and self.anonymous_key: raise ValidationError( _('A user id or an anonymous key must be associated with a post, ' 'but not both.')) if self.anonymous_key and not self.username: raise ValidationError( _('A username must be specified if the poster is anonymous')) def save(self, *args, **kwargs): new_post = self.pk is None super(AbstractPost, self).save(*args, **kwargs) # Ensures that the subject of the thread corresponds to the one associated # with the first post. Do the same with the 'approved' flag. if (new_post and self.topic.first_post is None) or self.is_topic_head: if self.subject != self.topic.subject or self.approved != self.topic.approved: self.topic.subject = self.subject self.topic.approved = self.approved # Trigger the topic-level trackers update self.topic.update_trackers() def delete(self, using=None): if self.is_alone: # The default way of operating is to trigger the deletion of the associated topic # only if the considered post is the only post embedded in the topic self.topic.delete() else: super(AbstractPost, self).delete(using) self.topic.update_trackers()
class AbstractTopic(DatedModel): """ Represents a forum topic. """ forum = models.ForeignKey('forum.Forum', related_name='topics', on_delete=models.CASCADE, verbose_name=_('Topic forum')) poster = models.ForeignKey( settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.CASCADE, verbose_name=_('Poster'), ) # The subject of the thread should correspond to the one associated with the first post subject = models.CharField(max_length=255, verbose_name=_('Subject')) tags = models.CharField(verbose_name=_('Tags'), max_length=255) slug = models.SlugField(max_length=255, verbose_name=_('Slug')) tokens = SetTextField(base_field=models.CharField(max_length=255), null=True) # Sticky, Announce, Global topic or Default topic ; that's what a topic can be TOPIC_POST, TOPIC_STICKY, TOPIC_ANNOUNCE, TOPIC_TIPS, TOPIC_STUDY_MATERIALS, TOPIC_NEWS_STORIES = 0, 1, 2, 3, 4, 5 TYPE_CHOICES = ( (TOPIC_POST, _('Default topic')), (TOPIC_STICKY, _('Sticky')), (TOPIC_ANNOUNCE, _('Announce')), (TOPIC_TIPS, _('Tips and Tricks')), (TOPIC_STUDY_MATERIALS, _('Study Materials')), (TOPIC_NEWS_STORIES, _('News Stories')), ) type = models.PositiveSmallIntegerField(choices=TYPE_CHOICES, verbose_name=_('Topic type'), db_index=True) # A topic can be locked, unlocked or moved TOPIC_UNLOCKED, TOPIC_LOCKED, TOPIC_MOVED = 0, 1, 2 STATUS_CHOICES = ( (TOPIC_UNLOCKED, _('Topic unlocked')), (TOPIC_LOCKED, _('Topic locked')), (TOPIC_MOVED, _('Topic moved')), ) status = models.PositiveIntegerField(choices=STATUS_CHOICES, verbose_name=_('Topic status'), db_index=True) # A topic can be approved before publishing ; defaults to True. The value of this flag # should correspond to the one associated with the first post approved = models.BooleanField(verbose_name=_('Approved'), default=True, db_index=True) # The number of posts included in this topic (only those that are approved) posts_count = models.PositiveIntegerField(verbose_name=_('Posts count'), editable=False, blank=True, default=0) # The number of time the topic has been viewed views_count = models.PositiveIntegerField(verbose_name=_('Views count'), editable=False, blank=True, default=0) # The date of the latest post last_post_on = models.DateTimeField(verbose_name=_('Last post added on'), blank=True, null=True) # The first post and the last post of the topic. The first post can be unnaproved. The last post # must be approved first_post = models.ForeignKey('forum_conversation.Post', editable=False, related_name='+', blank=True, null=True, on_delete=models.SET_NULL, verbose_name=_('First post')) last_post = models.ForeignKey('forum_conversation.Post', editable=False, related_name='+', blank=True, null=True, on_delete=models.SET_NULL, verbose_name=_('Last post')) # Many users can subscribe to this topic subscribers = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='topic_subscriptions', blank=True, verbose_name=_('Subscribers')) objects = models.Manager() approved_objects = ApprovedManager() class Meta: abstract = True app_label = 'forum_conversation' ordering = [ '-type', '-last_post_on', ] get_latest_by = 'last_post_on' verbose_name = _('Topic') verbose_name_plural = _('Topics') def __str__(self): return self.first_post.subject if self.first_post is not None else self.subject @property def is_topic(self): """ Returns True if the topic is a default topic. """ return self.type == self.TOPIC_POST @property def is_sticky(self): """ Returns True if the topic is a sticky topic. """ return self.type == self.TOPIC_STICKY @property def is_announce(self): """ Returns True if the topic is an announce. """ return self.type == self.TOPIC_ANNOUNCE @property def is_tips(self): """ Returns True if the topic is an announce. """ return self.type == self.TOPIC_TIPS @property def is_studymaterials(self): """ Returns True if the topic is an announce. """ return self.type == self.TOPIC_STUDY_MATERIALS @property def is_newsstories(self): """ Returns True if the topic is an announce. """ return self.type == self.TOPIC_NEWS_STORIES @property def is_locked(self): """ Returns True if the topic is locked. """ return self.status == self.TOPIC_LOCKED def has_subscriber(self, user): """ Returns True if the given user is a subscriber of this topic. """ if not hasattr(self, '_subscribers'): self._subscribers = list(self.subscribers.all()) return user in self._subscribers def clean(self): super(AbstractTopic, self).clean() if self.forum.is_category or self.forum.is_link: raise ValidationError( _('A topic can not be associated with a category or a link forum' )) def save(self, *args, **kwargs): # It is vital to track the changes of the forum associated with a topic in order to # maintain counters up-to-date. old_instance = None if self.pk: old_instance = self.__class__._default_manager.get(pk=self.pk) # Update the slug field self.slug = slugify(force_text(self.subject), allow_unicode=True) # Do the save super(AbstractTopic, self).save(*args, **kwargs) # If any change has been made to the parent forum, trigger the update of the counters if old_instance and old_instance.forum != self.forum: self.update_trackers() # The previous parent forum counters should also be updated if old_instance.forum: old_forum = old_instance.forum old_forum.refresh_from_db() old_forum.update_trackers() def _simple_save(self, *args, **kwargs): """ Calls the parent save method in order to avoid the checks for topic forum changes which can result in triggering a new update of the counters associated with the current topic. This allow the database to not be hit by such checks during very common and regular operations such as those provided by the update_trackers function; indeed these operations will never result in an update of a topic's forum. """ super(AbstractTopic, self).save(*args, **kwargs) def delete(self, using=None): super(AbstractTopic, self).delete(using) self.forum.update_trackers() def update_trackers(self): """ Updates the posts count, the update date and the link toward the last post associated with the current topic. """ self.posts_count = self.posts.filter(approved=True).count() first_post = self.posts.all().order_by('created').first() last_post = self.posts.filter( approved=True).order_by('-created').first() self.first_post = first_post self.last_post = last_post self.last_post_on = last_post.created if last_post else None self._simple_save() # Trigger the forum-level trackers update self.forum.update_trackers()
def test_int(self): field = SetTextField(models.IntegerField(), max_length=32) assert field.description == "Set of Integer"
class BigIntSetModel(Model): field = SetTextField(base_field=IntegerField())
class BigCharSetModel(Model): field = SetTextField( base_field=CharField(max_length=8), max_length=32, )