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

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.

Related

How to filter in Django Rest Framework function based view?

So many documentation for filtering in Django rest framework but all the examples are in class based view. but I am trying to do the same in DRF function based view. I wanted to do multiple filter for my items queryset.
I tried one way and it is working perfectly. Here first I am trying to search by item name or restaurant name in one request. then I take another keyword and try to filter restaurant name or item name based on restaurant city. It is working perfectly like if I hit this url
http://localhost:8000/api/items/?keyword=lasagne&keyword1=paris
then it gives me the perfect response.
But What I am asking for is that now my code looks for this specific part is messy and I want to add more fields for multiple filtering. Which procedure to follow? Should I follow this one and multiple requests and trying to filter from this.
Suppose now I want to filter the queryset based on dish_type, price, item_type, location and then search for items by name or restaurants by name
#this is my models
class Restaurant(models.Model):
user = models.OneToOneField(CustomUser, related_name='restaurant', on_delete=models.CASCADE, null=False)
name = models.CharField(max_length=200, blank=True, null=True)
profile_picture = models.ImageField(null=True, blank=True)
address = models.TextField(max_length=2000, blank=True, null=True)
city = models.CharField(max_length=200)
latitude = models.DecimalField(max_digits = 13, decimal_places = 7, blank=True, null=True)
longitude = models.DecimalField(max_digits = 13, decimal_places = 7, blank=True, null=True)
is_verified = models.BooleanField(default=False)
createdAt = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.name)
class Item(models.Model):
user = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
name = models.CharField(max_length=220)
image = models.ImageField(null=True, blank=True)
dish_type = models.ForeignKey(Dishtype, on_delete=models.CASCADE)
item_type = models.ForeignKey(Itemtype, on_delete=models.CASCADE)
description = models.TextField(max_length=10000)
rating = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True)
numReviews = models.IntegerField(null=True, blank=True, default=0)
old_price = models.DecimalField(max_digits=11, decimal_places=2)
discount = models.IntegerField(blank=True, null=True)
price = models.DecimalField(max_digits=12, decimal_places=2, blank=True, null=True)
countInStock = models.IntegerField(blank=True, null=True, default=0)
createdAt = models.DateTimeField(auto_now_add=True)
_id = models.AutoField(primary_key=True, editable=False)
def save(self, *args, **kwargs):
self.price = Decimal(self.old_price * (100 - self.discount) / 100)
return super(Item, self).save(*args, **kwargs)
class Meta:
ordering = ['-createdAt']
def __str__(self):
return self.name
#serializer
class RestaurantSerializer(serializers.ModelSerializer):
user = serializers.SerializerMethodField(read_only=True)
class Meta:
model = Restaurant
fields = '__all__'
def get_user(self, obj):
user = obj.user
serializer = UserSerializer(user, many=False)
return serializer.data
class ItemSerializer(serializers.ModelSerializer):
user = serializers.SerializerMethodField(read_only=True)
dish_type = serializers.SerializerMethodField(read_only=True)
item_type = serializers.SerializerMethodField(read_only=True)
class Meta:
model = Item
fields = '__all__'
def get_user(self, obj):
user = obj.user
serializer = RestaurantSerializer(user, many=False)
return serializer.data
def get_dish_type(self, obj):
dish_type = obj.dish_type
serializer = DishtypeSerializer(dish_type, many=False)
return serializer.data
def get_item_type(self, obj):
item_type = obj.item_type
serializer = ItemtypeSerializer(item_type, many=False)
return serializer.data
#views.py
#api_view(['GET'])
#permission_classes([IsAuthenticated])
def getItems(request):
user = request.user
query = request.query_params.get('keyword')
if query == None:
query = ''
cuery = request.query_params.get('keyword1')
if cuery == None:
cuery = ''
items = Item.objects.select_related('user').select_related('dish_type').select_related('item_type').all().filter(
Q(name__icontains = query) | Q(user__name__icontains = query))
else:
restaurant_city = Item.objects.select_related('user').select_related('dish_type').select_related('item_type').all(
).filter(Q(user__city__iexact = cuery))
items = restaurant_city.filter(Q(name__icontains = query) | Q(user__name__icontains = query))
serializer = ItemSerializer(items, many=True)
return Response(serializer.data)
######Updated solved the problem
#filters.py
class ItemFilter(django_filters.FilterSet):
numReviews = django_filters.NumberFilter()
numReviews__gt = django_filters.NumberFilter(field_name='numReviews', lookup_expr='gt')
numReviews__lt = django_filters.NumberFilter(field_name='numReviews', lookup_expr='lt')
name = django_filters.CharFilter(lookup_expr='icontains')
class Meta:
model = Item
fields = ['_id', 'dish_type__id']
#views
#api_view(['GET'])
#permission_classes([IsAuthenticated])
def getItems(request):
user = request.user
queryset = Item.objects.all()
filterset = ItemFilter(request.GET, queryset=queryset)
if filterset.is_valid():
queryset = filterset.qs
serializer = ItemSerializer(queryset, many=True)
return Response(serializer.data)
now data are passing like this
http://localhost:8000/api/items/?numReviews__gt=20&numReviews__lt=22
You can use queryset and override get_queryset function.
class FooViewSet(GenericViewSet, mixins.ListModelMixin):
authentication_classes = [JSONWebTokenAuthentication]
permission_classes = [IsAuthenticated]
serializer_class = ItemSerializer
def get_queryset(self):
query = self.request.query_params.get('keyword', '')
if not self.request.query_params.get('keyword1'):
items = Item.objects.select_related('user').select_related('dish_type').select_related(
'item_type').all().filter(
Q(name__icontains=query) | Q(user__name__icontains=query))
else:
restaurant_city = Item.objects.select_related('user').select_related('dish_type').select_related(
'item_type').all(
).filter(Q(user__city__iexact=self.request.query_params.get('keyword1', '')))
items = restaurant_city.filter(Q(name__icontains=query) | Q(user__name__icontains=query))
return items

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

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 update a field in the model using ForegnKey lookup?

I need to be able to update a field num_places in the Event model accessing it via event ForeignKey in the Participant model when the last is saved.
Here are my models.py:
class Event(models.Model):
name = models.CharField(max_length=50)
description = models.CharField(max_length=500)
text = models.TextField()
image = models.ImageField(blank=True)
date = models.DateTimeField()
price = models.PositiveIntegerField()
num_places = models.PositiveIntegerField(default=50)
slug = models.SlugField()
class Participant(models.Model):
name = models.CharField(max_length=200)
participant_uuid = models.UUIDField(primary_key=False, verbose_name='UUID')
email = models.EmailField()
phone_regex = RegexValidator(regex=r'^\+7\d{10}$')
phone_number = models.CharField(validators=[phone_regex], max_length=12)
num_places = models.PositiveIntegerField(default=1)
event = models.ForeignKey(Event, on_delete=models.CASCADE)
paid = models.BooleanField(default=False)
def __str__(self):
return self.name
def save(self, *args, **kwargs):
try:
self.full_clean(exclude=None)
self.event.num_places -= self.num_places # the value isn't updated
super().save(*args, **kwargs)
self.valid = True
self.non_field_errors = False
except ValidationError as e:
self.non_field_errors = e.message_dict[NON_FIELD_ERRORS]
self.valid = False
class Meta:
unique_together = ('name', 'email', 'phone_number', 'event')
The code with a comment has a problem: the num_places value in the Event model stays unchanged. How to fix it?
you need to save the modified object of Event.
self.event.save()
def save(self, *args, **kwargs):
try:
self.full_clean(exclude=None)
self.event.num_places -= self.num_places # the value isn't updated
self.event.save()
"""watch out this since you wanna do it at the end after setting valid, and non_fieild_errors"""
super().save(*args, **kwargs)
self.valid = True
self.non_field_errors = False
except ValidationError as e:
self.non_field_errors = e.message_dict[NON_FIELD_ERRORS]
self.valid = False

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?