How to Get all (user followings posts) in django rest framework views - filter

relative to this answer: How to make follower-following system with django model
I will like to know how to get all the post of the user that I'm following just in case I'll want to add that extra functionality in the future.

You will have an another Model Post associated with User.
class Post(models.Model):
description = models.TextField()
user = models.ForeignKey("User", related_name="posts")
Getting all posts of following_user_id, you can achieve by below query
following_user_ids = request.user.followers.all().values_list("following_user_id", flat=True)
posts = Post.objects.filter(user__in=following_user_ids)
request.user is the logged-in user, related_name="followers" is used get all associated records from UserFollowing Model. values_list() will return the following_user_id in list form than pass the returned list in Post

Related

How to save Foreign Key values in DJANGO REST?

Let's say i have models like follow.
class Department(models.Model):
name = models.CharField(max_length=255)
class Student(models.Model):
department = models.Foreignkey(Department, on_delete=models.CASCADE)
name = models.CharField(max_length=255)
Now i need to set Department(which is created already) of the Student whenever i create the student instance.
which is best practice
i) Sending the department id in URI like `departments/{pk}/students`
ii) sending department id in body parameter
It is always better to send the sensitive data like ids as Post request instead of passing as URL args. if you really want to pass data in URL then please use slugs instead of ID.
also, you can use DRF model serializer to save the data
in this case, It'd be better to send department id in the body and keep the endpoint simple as
{base}/api/student/
make an HTTP POST to this endpoint
{
"department_id":"",
.
.
}
by taking a look at this endpoint this clearly shows endpoint for operations involving student object, I'd say it's more close to REST standards.

Update Foreign-key Related Instance on Post Request

I am trying to implement a system where a user can subscribe to a company. For that I have to implement the following flow:
User registers
User klicks on a button to subscribe to a company
User has to enter a code (every company has a secret code. By possession the user proves that he is somewhat related to the company)
User is subscribed
For this, I have to implement an API endpoint that receives the code by the user (the user is authenticated at this point).
It is shameful, but I am lost: I am thinking of implementing a view like this.
class RegisterUserToCustomer(APIView):
permission_classes = (permissions.IsAuthenticated,)
def post(self, request, format=None):
serializer = CustomerSerializer(data=request.data)
if serializer.is_valid():
serializer.save(user=self.request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.data, status=status.HTTP_400_BAD_REQUEST)
Obviously, I have to:
Receive the code from the user via POST method
Search the database and figure out, if the code corresponds to any company
Edit the ForeignKey field on the user and link it to the company
But where would I implement this logic. With my limited experience I see three possibilities:
Call serializer.save() and write a custom create() method (but I don't want to create anything so this seems like bad practice
Implement this logic in the view, but I want to access the code from the validated_data (this seems like a problem?)
Can I write a custom save() method for the serializer? Are there any examples for a custom save() method since the original drf save() method contains a lot of validation logic.
Obviously I don't expect you guys to write the whole code for me, but maybe someone has somewhat of a blueprint of how and where to implement this?
Steps to do this:
Create a field company_code in Customer table and make that
field as Foreign key.
Create a Serializer with that foreign key field.
Create a viewset or generic views to expect that field from Post method as Id of the Company. Use save() method to store foreign key.
This scenarios is only for Subscribe one organisation, if you're able to subscribe multiple organisation make that field as ManytoMany field.
Refer the code sample,
Models.py
class Customer(models.Model):
# customer related field
name = models.CharField(max_length=20)
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
Serializer.py
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('name', 'organization', )
Views.py
class CustomerViewSet(viewsets.ModelViewSet):
serializer_class = CustomerSerializer
queryset = Customer.objects.all()
Request data(POST Json)
{
"name": "test",
"organization": "id-of company"
}

How to pass variable id from AngularJS to Django for SQL query

I have a table of employees when I click a row it will get the Id of the row and pass it to django sql query.
This is my raw sql query in django
class GetEmployeeDetailsApi(ListAPIView):
queryset = EmployeeTb.objects.raw('SELECT *
FROM EmployeTable
WHERE EmployeeId = %s', [id])
serializer_class = GetEmployeeDetailsSerializer
I already tried another a way to do this by fetching all records then filter it in front-end and it worked, but I do not want to do this because of security reasons, it exposes the whole table when I only need one record.
I think you want a view that extends ModelViewSet. This provides a full object list, plus the ability to retrieve individual objects.
http://www.django-rest-framework.org/api-guide/viewsets/#modelviewset
class EmployeeDetailsViewSet(viewsets.ModelViewSet):
queryset = EmployeeTb.objects.all()
serializer_class = GetEmployeeDetailsSerializer
I suggest you work through the DRF tutorial, which covers basic concepts like this:
http://www.django-rest-framework.org/tutorial/quickstart/

Django rest framework - Raising exception / Handling empty results while filtering

I have a user profile class and am checking if a user exists and if not want to create that user.
Am using the filter class for userprofile so that the client can call :
http://localhost:8000/users/?email=a#b.com
and if the result is empty will create a user with the email address.
Is there a way to intercept the query result and raise an exception when its empty and handle that to create the user.
If there is a better way would like to be corrected as well.
class UserQueryFilter(django_filters.rest_framework.FilterSet):
email = django_filters.CharFilter(name="user__email")
username = django_filters.CharFilter(name="user__username")
class Meta:
model = UserProfile
fields = ['email', 'username']
class UserViewSet(viewsets.ReadOnlyModelViewSet):
queryset = UserProfile.objects.all()
serializer_class = UserSerializer
filter_class = UserQueryFilter
Any help is appreciated.
Thanks
Anand
Django Rest Framework provide a functionality that is disabled by default. Maybe it could give you another approach to resolve your problem: PUT as create
In other hand, if you really need to create the user through a GET request with a querystring, you can use a MethodFilter from django-filters, for example:
class UserFilters(FilterSet):
user = MethodFilter(action='filter_user')
class Meta:
model = User
fields = ['user']
def filter_user(self, queryset, value):
if not value:
# Here Raise Exception
else:
# Check if the user exists, if not create it
users = queryset.filter(Q(username=value) | Q(email=value))
if not users.exists:
user = User.objects.create(...)
return queryset.filter(pk=user.id)
else:
return users
Hope this can help you. I'm not pretty sure about it works in that exact way but it's the idea.
Personally, I recommend you that try to execute that tasks through a more appropriate request like POST or PUT and manage in the corresponding method.

Django ModelForms: Trying to save a form using a foreign key ID

I'm trying to create a new Topic and the category id is dynamically determined in javascript on the client side. The problem i'm having is I pass the category id and I want to lookup the correct category object, but using a model form, it checks if the category is an instance of Category before I can assign it and save it.
--model.py--
class Topic(models.Model):
category = models.ForeignKey(Category)
--form.py--
class TopicForm(ModelForm):
category = forms.IntegerField(widget=forms.HiddenInput())
class Meta:
model = Topic
fields = ('category')
--view.py--
form = TopicForm(request.POST)
if form.is_valid():
form.save(commit=False) # throws exception category is not a Category instance
form.category = Category.objects.get(pk=form.cleaned_data.get('category'))
form.save()
Use a ModelChoiceField instead of the IntegerField in your form. See the built-in fields reference
Following Oggy's suggestion, I changed it to a ModelChoiceField and now Django does all the magic behind the scenes.
category = forms.ModelChoiceField(Category.objects.all(), widget=forms.HiddenInput())
Now I hope the queryset doesn't get evaluated, since it's not necessary and there are 90,000 records. :)

Resources