Django: how to create groups? - django

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)

Related

Django Public user profile + user's posts

I hope you're well. I'm beginning with Django.
I'd like to create - like facebook - a public profile. I've already created a UserProfileUpdateView with country, adresse, image, ...
When a user post something I'd like to have a link to his public profile (country, adresse, image, ... + posts):
class UserPostView(ListView):
template_name = 'user_post.html'
model = Post
context_object_name = 'posts'
def get_context_data(self, **kwargs):
context = super(UserProfileView, self).get_context_data(**kwargs)
context['userprofile'] = UserProfile.objects.get(user=self.request.user)
return context
def get_queryset(self):
return Post.objects.filter(user=self.kwargs['pk'])
A - I'd like to display the public profile link with username (which is unique) and not with a number. Does anyone has an idea about how I can solve this?
path('<int:pk>/',UserPostView.as_view(),name="user_posts"),
UserProfile (user app)
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
street = models.CharField(null=True,blank=True,max_length=300)
number_street = models.CharField(null=True,blank=True,max_length=20)
street_detail = models.CharField(null=True,blank=True,max_length=300)
town = models.CharField(null=True,blank=True,max_length=60)
zipcode = models.CharField(null=True,blank=True,max_length=20)
country = models.CharField(null=True,blank=True,max_length=60)
image = models.ImageField(null=True,blank=True,default='user/user-128.png', upload_to='user/')
slug = models.SlugField(editable=False)
def save(self, *args,**kwargs):
self.slug = slugify(self.user.username)
super(UserProfile, self).save(*args, **kwargs)
img = Image.open(self.image.path)
if img.height > 200 or img.width > 200:
new_size = (200, 200)
img.thumbnail(new_size)
img.save(self.image.path)
def __str__(self):
return self.user.username
Post (nutriscore app)
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=None)
author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
updated_on = models.DateTimeField(auto_now= True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = unique_slugify(self, slugify(self.title))
super().save(*args, **kwargs)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
If the user in the Post model is a foreign key and is from django.contrib.auth.models.User, then first scan the User table from username and then scan the UserProfile table using the id as follows
user = User.objects.filter(username=name).values()
user_id = user[0]['id'] # You get the id of the user
userprofile = UserProfile.objects.filter(user_id=userprofile).values() # Scan the UserProfile table using the id obtained above
user_post = Post.objects.filter(user = user_id) # post by authenticated user

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.

Problems with converting datetime to string in Django

I can't understand why this isn't working because in a Python console it works fine for me...
class Activity(models.Model):
id = models.CharField(max_length=250, primary_key=True)
description = models.CharField(max_length=255, null=False, help_text="Brief description of the activity")
start = models.DateTimeField(default=timezone.now, verbose_name="Planned start date/time", blank=True)
end = models.DateTimeField(default=timezone.now, verbose_name="Planned completion date/time", blank=True)
class Meta:
verbose_name_plural = 'Activities'
def save(self, *args, **kwargs):
self.id = "%s-%s" % (self.description, str(self.start.date()))
super(Activity, self).save(*args, **kwargs)
def __str__(self):
"""
String for representing the Model object (in Admin site etc.)
"""
return f'{self.description}'
But what I get for my self.id field is (using "xx" as description):
"xx-<built-in method date of datetime.datetime object at 0x000001FCBAAA51E0>"
Try to use strftime instead
def save(self, *args, **kwargs):
self.id = "%s-%s" % (self.description, self.start.strftime('%m/%d/%Y'))
super(Activity, self).save(*args, **kwargs)

Cannot auto add group in 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)

Restrict django form ForeignKey dropdown by user

I have two models, Group, and List Item. List Items belong inside Groups:
class List_Item(models.Model):
name = models.CharField("List Item Name", max_length=200, unique = True)
group = models.ForeignKey(Group, verbose_name="Group")
creation_date = models.DateTimeField("Creation Date", default=datetime.now)
notes = models.TextField("Notes", blank=True)
user = models.ForeignKey(User, editable=False)
def __unicode__(self):
return self.name
class Group(models.Model):
name = models.CharField("Group Name", max_length=200, unique = True)
notes = models.TextField("Notes", blank=True)
user = models.ForeignKey(User, editable=False)
def __unicode__(self):
return self.name
In my forms for List Items, a ModelForm has a dropdown for Groups. Currently, it lists all Groups, regardless of which user a Group belongs to. But I want to only display Groups that belong to the user logged in. How might I do this?
You would have to override the form field inside the init method. You could pass the logged in user to the form from the view and filter based on it
#form
class ListItemform(forms.ModelForm):
def __init__(self, *args, ** kwargs):
self.user = kwargs.pop('user', None)
super(ListItemform, self).__init__(*args, **kwargs)
self.fields['group'].queryset = Group.objects.filter(user = self.user)
#view
def displayform(request):
user = request.user
form = ListItemForm(user = user)
return ...