Cannot auto add group in Django - django

I am using Django 1.6 and have a CustomUser.
I want all users that are created to be added to a group by default.
I have tried to add it to the save method for my user but its not working.
class MyUser(AbstractBaseUser, PermissionsMixin):
name = models.CharField(max_length=200)
section = models.CharField(max_length=200, null=True)
department = models.ForeignKey(Department, null=True)
...
objects = MyUserManager()
def save(self, *args, **kwargs):
group = Group.objects.get(name='myhistory')
self.groups.add(group)
self.section="testing it saves"
super(MyUser, self).save(*args, **kwargs)
It does call the save method as it sets the section as above - but wont set the group.
It finds the group fine - just no setting it.
Can anyone help?

I think you have missed indentation,
class MyUser(AbstractBaseUser, PermissionsMixin):
name = models.CharField(max_length=200)
section = models.CharField(max_length=200, null=True)
department = models.ForeignKey(Department, null=True)
...
objects = MyUserManager()
def save(self, *args, **kwargs):
group = Group.objects.get(name='myhistory')
self.groups.add(group)
self.section="testing it saves"
super(SCVUser, self).save(*args, **kwargs)

Related

How to create slug of many to many fields in django?

I want to make slugs on post save for my model using three fields one charfield and two ManytoMany Fields but getting error during saving.
Here is my code:
Heading ##class product(models.Model):
id = models.AutoField(primary_key=True)
image = models.ForeignKey(all_images, verbose_name='Product Images', on_delete=models.CASCADE, related_name='proimages')
ProductName = models.CharField(max_length=200, null=False,default="None", blank=False,verbose_name="Product Name")
CategoryName = models.ManyToManyField(category,related_name='procat', blank=False,verbose_name="Category Name")
SubcatName = models.ManyToManyField(subcategory,related_name='prosubcat', blank=False,verbose_name="Sub-category Name")
description = RichTextUploadingField(blank= False,verbose_name="Description")
price = models.IntegerField(default=100, null=True, blank=True, verbose_name='Price')
slug = models.SlugField(max_length=55, blank=True, null=True)
def get_slug(self):
slug = self.ProductName
try:
for items in self.SubcatName.all():
slug +=items.name
try:
for items in self.CategoryName.all():
slug +=items.CategoryName
except:
pass
except:
pass
return slugify(slug)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = self.get_slug()
super(product, self).save(*args, **kwargs)

Django: how to create groups?

EXAMPLE to elaborate my problem -> I am the user of the website and i want to create a group. While creating group the website asked me the group_name,group_description ,group_password (as i don't want the group to be public and a person if want to join the group should know the password). now i have given the name and the password to my friends and they can join the group by authenticating with the password of group to successfully join.
ISSUE i am facing -> i have created the password field in models.py. But the password is saved in the database as plane text but not something liked hashed django passwords. secondly, i want in the joining user to authenticate with the password in order to join the group.
models.py
class Group(models.Model):
admin = models.ForeignKey(to=Profile, related_name="admin", on_delete=models.CASCADE)
name = models.CharField(max_length=200, unique=True)
password = models.CharField(max_length=200, default='thinkgroupy')
slug = models.SlugField(allow_unicode=True, unique=True)
group_pic = models.ImageField(upload_to="users/group_images/%y/%m/%d",null=True)
about = models.CharField(max_length=255, null=True, blank=True)
about_html = models.TextField(editable=False, default='', blank=True)
created_at = models.DateTimeField(auto_now=True)
members = models.ManyToManyField(User, through="GroupMember")
def __str__(self):
return "%s" % self.name
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
self.about_html = misaka.html(self.about)
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse("groups:single", kwargs={"slug": self.slug})
class Meta:
ordering = ["name"]
class GroupMember(models.Model):
group = models.ForeignKey(Group, related_name="memberships")
user = models.ForeignKey(User,related_name='user_groups')
def __str__(self):
return self.user.username
class Meta:
unique_together = ("group", "user")
views.py
class CreateGroup(LoginRequiredMixin, generic.CreateView):
fields = ("name", "description","password")
model = Group
class JoinGroup(LoginRequiredMixin, generic.RedirectView):
def get_redirect_url(self, *args, **kwargs):
return reverse("groups:single",kwargs={"slug": self.kwargs.get("slug")})
def get(self, request, *args, **kwargs):
group = get_object_or_404(Group,slug=self.kwargs.get("slug"))
try:
GroupMember.objects.create(user=self.request.user,group=group)
except IntegrityError:
messages.warning(self.request,("Warning, already a member of {}".format(group.name)))
else:
messages.success(self.request,"You are now a member of the {} group.".format(group.name))
return super().get(request, *args, **kwargs)

Slugify self.title + random numbers

I hope you're well. I've two questions for you:
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
url_image = models.URLField(max_length=200, default='SOME STRING')
author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
updated_on = models.DateTimeField(auto_now= True)
name_site = models.CharField(max_length=200, default='NA')
url_site = models.URLField(max_length=200, default='https://exemple.fr/')
content = models.TextField()
I. I want my title (unique=False) because I have some similar titles. So is it possible to save my slug (editable=False) with slugify with something like that:
slug_str = "%s %s" % (self.title, 4 random numbers like that 0476)
If anyone has a better idea, I'm interested in
Thanks a lot :) have a good holidays and take care
Here are a couple functions that I use. You pass in the model instance and the desired title into unique_slugify which will continue trying to add random strings until one is created that doesn't already exist.
import random
import string
def random_string_generator(size=10, chars=string.ascii_lowercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
def unique_slugify(instance, slug):
model = instance.__class__
unique_slug = slug
while model.objects.filter(slug=unique_slug).exists():
unique_slug = slug
unique_slug += random_string_generator(size=4)
return unique_slug
I usually use it by overriding the model save method.
class YourModel(models.Model):
slug = models.SlugField(max_length=200, unique=True)
title = models.CharField(max_length=200)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = unique_slugify(self, slugify(self.title))
super().save(*args, **kwargs)
in my opinion, it doesn't make sens two posts may have the same title even with two different slugs, it even confuses readers and even worst it's very bad for SEO. i suggest you to avoid this path and try to review the logic
in models.py
class Post(models.Model):
title = models.CharField(_('title'), max_length=200,
unique=True, # title should be unique
help_text=_('The title of the entry.')
)
slug = models.SlugField(_('slug'), max_length=200,
unique=True, null=True, blank=True,
help_text=_(
'If blank, the slug will be generated automatically '
'from the given title.'
)
)
[..]
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title) # here you don't need to add random numbers since the title is already unque
super().save(*args, **kwargs)
in admin.py
class PostAdmin(admin.ModelAdmin):
list_display = ('title', .. )
readonly_fields = ('slug', .. ) # Add slug to read_only fields to make it not editable if you want

How to display two not associated models on one page via admin interface?

I have two models, not connected by ForeignKey. I would to display them on one page in admin interface, in the way like inlines in Django.
I can't associate PostFile with Post, because uploaded medias should be available to every Post which was and will be created in future. I have no idea what I can do if inlines are unavailable.
class Post(models.Model):
STATUS_CHOICES = (
('draft', 'Draft'),
('published', 'Published')
)
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255, unique_for_date='publish_date', blank=True)
author = models.ForeignKey(User, related_name='blog_posts', on_delete=models.CASCADE, blank=True)
content = MarkdownxField()
publish_date = models.DateTimeField(default=timezone.now)
creation_date = models.DateTimeField(auto_now_add=True)
last_update_date = models.DateField(auto_now=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
tags = models.ManyToManyField(Tag)
objects = models.Manager()
class Meta:
ordering = [
'-publish_date'
]
def __str__(self):
return self.title
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
def get_absolute_url(self):
return reverse('blog:post_detail',
args=[
self.publish_date.strftime('%Y'),
self.publish_date.strftime('%m'),
self.publish_date.strftime('%d'),
self.slug
])
#https://github.com/neutronX/django-markdownx/issues/83
def formatted_markdown(self):
return markdownify(self.content)
class PostFile(models.Model):
file_name = models.CharField(max_length=200, blank=True)
file_object = models.FileField(upload_to='post_files/')
file_upload_date = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
if not self.file_name:
self.file_name = self.file_object.name
super(PostFile, self).save(*args, **kwargs)
def file_url(self):
return self.file_object.url
def __str__(self):
return self.file_name
I would to receive in output a Post model admin page, where on the bottom I have listed all PostFile objects. This will give me easy and fast acces to PostFile-object url on media folder. I don't want each time to open new tab, and to go to PostFile model admin page to check url of object.

Set ManyToMany field in model save method

I have a problem, I try to save the model and only adds to 'members' the users that belong to the company set in the field 'company'.
This is my code:
class GroupFolderAccess(BaseModel):
name = models.CharField(max_length=128)
members = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, related_name='belongs')
company = models.ForeignKey('Company', on_delete=models.CASCADE, related_name='folders')
folder = models.ForeignKey('recourse.Folder', null=True, blank=True, on_delete=models.CASCADE, related_name='get_group')
def save(self, *args, **kwargs):
for member in self.members.all():
if self.company != member.company:
print(member)
self.members.remove(member)
return super(GroupFolderAccess, self).save(*args, **kwargs)
When I save, it displays users correctly, but does not remove them from the relationship.