Django Public user profile + user's posts - django

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

Related

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)

Django: Delete or empty content of a row in UpdateView

I'm looking to delete or empty a specific row in my table/model in my UpdateView. I have a team and employees in the team. I have made an update view that when "yes" is pressed, the team becomes archived. I want to additionally delete or empty the employee's numbers when doing so. How would I approach that?
I know it might be weird, but the idea is that the employee's numbers should be destroyed once the team is archived, while the rest of the data still stands.
Team Model
class Team(models.Model):
slug = models.SlugField(max_length=200)
teamname = models.CharField(max_length=50, help_text="Indtast holdnavn.", null=False, primary_key=True)
is_active = models.BooleanField(default=True)
Employee Model
class Employee(models.Model):
id = models.AutoField(primary_key=True)
slug = models.SlugField(max_length=200)
emp_num = models.IntegerField(help_text="Indtast medarbejderens MA-nummer. (F.eks 123456)")
firstname = models.CharField(max_length=30, help_text="Indtast medarbejderens fornavn.")
lastname = models.CharField(max_length=30, help_text="Indtast medarbejderens efternavn.")
teamname = models.ForeignKey('Hold', on_delete=models.CASCADE, null=True)
UpdateView
My updateView is using team, as its that model I'm updating.
class ArchiveHoldView(UpdateView):
template_name = 'evalsys/medarbejder/archive_hold.html'
model = Team
form_class = ArchiveForm
def archive_view_team_with_pk(self, slug=None):
if slug:
team = Team.objects.get(slug=slug)
else:
team = self.team
args = {'team': team}
return render(self, 'evalsys/medarbejder/archive_hold.html', args)
def get_context_data(self, **kwargs):
context = super(ArchiveHoldView, self).get_context_data(**kwargs)
context['is_active'] = Team.objects.get(slug=self.kwargs.get('slug'))
return context
def get_success_url(self):
return reverse_lazy("evalsys:home")
Update View form
class ArchiveForm(forms.ModelForm):
def save(self, *args, **kwargs):
self.instance.is_active = False
return super(ArchiveForm, self).save(*args, **kwargs)
is_active = BooleanField(required=False, widget=forms.HiddenInput())
class Meta:
model = Team
fields = ['is_active', ]
labels = {'is_active': 'Is Active'}

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.

How to update data in django model to title case in views?

I'm trying to change a column of strings like 'HOSPITAL ZERO', "HOSPITAL ONE" from the database into title case or 'Hospital zero' in the views.py or models.py. I've tried both and can't get either to work for me.
Here is my code in views.py. Column is in Hospital Model under name, i.e. Hospital.name.
def results(request):
if request.method == "GET":
Q=()
out_words = request.GET.get('s')
context = RequestContext(request)
#here is where I tried to change it
qs = Price.objects.annotate(hospital__name=Lower('hospital__name'))
table = PriceTable(qs.filter(service__desc_us__icontains = out_words))
RequestConfig(request, paginate={'per_page': 10}).configure(table)
RequestConfig(request).configure(table)
else:
table = PriceTable(Price.objects.all())
RequestConfig(request).configure(table)
return render(request, 'results.html', {'table': table})
Here is how I tried in model.py.
class Hospital(models.Model):
"""Model representing Hospitals."""
hid = models.CharField(max_length = 8, null=True)
name = models.CharField(max_length=200, primary_key=True)
hopid = models.UUIDField(default=uuid.uuid4, help_text='Unique ID for this particular hospital in database')
address = models.CharField(max_length = 200, null = True)
class Meta:
ordering = ['hopid']
#here is where i tried to update it
def save(self, *args, **kwargs):
self.name = self.name.title()
return super(Hospital, self).save(*args, **kwargs)
def __str__(self):
"""String for representing the Model object."""
return f'{self.name} ({self.address})'
class Price(models.Model):
"""Model with all the hospital prices by service."""
priceid = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text='Unique ID for this particular service in database')
comments = models.CharField(max_length = 200, blank = True, null =True)
hospital = models.ForeignKey("Hospital", on_delete=models.SET_NULL, null=True)
class Meta:
ordering =['priceid']
def __str__(self):
return f'{self.hospital.name} (...)'
You can try this:
"HOSPITAL ONE".lower().capitalize()
my_string.lower().capitalize()
Here is an option:
def save(self, *args, **kwargs):
self.name = self.name.lower().capitalize()
return super(Hospital, self).save(*args, **kwargs)
Here's a new method for your Hospital model called get_title_case_name. Now you can access a hospital name by calling hospital_instance.get_title_case_name().
class Hospital(models.Model):
"""Model representing Hospitals."""
hid = models.CharField(max_length = 8, null=True)
name = models.CharField(max_length=200, primary_key=True)
hopid = models.UUIDField(default=uuid.uuid4, help_text='Unique ID for this particular hospital in database')
address = models.CharField(max_length = 200, null = True)
class Meta:
ordering = ['hopid']
def __str__(self):
"""String for representing the Model object."""
return f'{self.name} ({self.address})'
def get_title_case_name(self):
return self.name.capitalize()
Just add method to model:
def get_title_case_name(self):
return self.name.title()
In views/template you can run this method against model object.

Django Form: form with ForeignKey

I'm making online shopping mall using Django(1.9.7) framework.
I think that showing codes is much easier than explaining in text.
models.py
class Product(TimeStampedModel):
name = models.CharField(max_length=120, unique=True)
slug = models.SlugField(null=True, blank=True)
description = models.TextField(max_length=400, blank=True)
is_active = models.BooleanField(default=True)
def __str__(self):
return self.name
class Variation(TimeStampedModel):
COLOR_CHOICES = (
('black', '흑백'),
('single', '단색'),
('multi', '컬러'),
)
price = models.DecimalField(
decimal_places=0,
max_digits=15,
blank=True,
null=True,
)
product = models.ForeignKey(Product)
color = models.CharField(
max_length=10,
choices=COLOR_CHOICES,
)
is_active = models.BooleanField(default=True)
class Meta:
unique_together = (('product', 'color'))
def __str__(self):
return str(self.product) + ' - ' + self.get_color_display()
I create form in my product_detail view and pass it as context data to template.
views.py
class ProductDetailView(DetailView):
model = Product
context_object_name = "product"
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
product = self.get_object()
context['cartitem_form'] = CartItemForm(product)
return context
What I want to do through form:
I want to show variations only related with given product. So I pass product as argument of form in view and save this product. And I'm trying to set the variation queryset through ModelChoiceField:
class CartItemForm(forms.ModelForm):
variation = forms.ModelChoiceField(
queryset=Variation.objects.filter(product=self.product)
)
class Meta:
model = CartItem
fields = (
'variation',
'width',
'height',
'quantity',
)
def __init__(self, *args, **kwargs):
self.product = kwargs.pop('product')
super().__init__(*args, **kwargs)
def save(self):
cart_item = super().save(commit=False)
cart_item.save()
return cart_item
but it doesn't work. How can I implement this?