Django Model advance Foreignkey Relation - django

I have a Django model which has relationship with user model. Where user are assigned to groups. especially "Admin", "Teacher","Student". So I want to make a foreign key relationship in such a way that it will show only The users that have been assigned to Teacher groups for Teacher_details model, And Similar for Student_Details Model. I have made the models Teacher_Details , Student_Details and established foreign key relation with User model. But the problem is that its showing all the user when I am filling Student_Details or Teacher_Details. Hope you got my problem.
I am hoping positive response.
The code looks like this:
class Student_Details(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
image = models.ImageField(default='none', upload_to='img/')
details_updated = models.DateTimeField(auto_now_add=True)
address = models.CharField(max_length=150)
admission_date = models.DateField()
previous_college = models.CharField(max_length=150)
course_enrolled = models.ForeignKey(ModelUniversity,on_delete=models.CASCADE)
semester = models.CharField(max_length=20,choices=semester,default=None)
def __str__(self):
return self.user.first_name
class Teacher_Details(models.Model):
address = models.CharField(max_length=150)
image = models.ImageField(default='none', upload_to='img/')
details_updated = models.DateTimeField(auto_now_add=True)
subject_taught = models.ManyToManyField(to='Student.stu_subject')
user = models.OneToOneField(User,on_delete=models.CASCADE)
def __str__(self):
return self.user.first_name
def subject_teacher_teaches(self):
return [str(s) for s in self.subject_taught.all()]

Since both models have a user_id reference, you could use that info to search both models based on the request and fetch the necessary instance. Make a view which checks the user_id in the request, search both models and return the results (I assume a user cannot belong to both groups...)

Related

Django models use id group as ForeignKey

I am developing one site and need to link table records to group id so I wrote my model for db but when I try to insert foreignkey i receive errors on makemigrations:
(fields.E300) Field defines a relation with model 'Group', which is either not installed, or is abstract.
and
sito_boe.Boe.group_id: (fields.E307) The field sito_boe.Boe.group_id was declared with a lazy reference to 'sito_boe.group', but app 'sito_boe' doesn't provide model 'group'
Here is my model.
I just searched on web and documentation without luck, Anyone can help me?
Here is my code:
from django.contrib.auth.models import Group
#Group.auth_group
class Boe(models.Model):
"""Model representing an author."""
Name = models.CharField(max_length=100,verbose_name="Nome")
Geo_POS = models.CharField(max_length=100,verbose_name="Coordinate")
Luogo = models.TextField(verbose_name="Posizione")
created_date = models.DateTimeField(default=timezone.now)
#group_id = models.CharField(max_length=100,verbose_name="Gruppo")
id_boa = models.CharField(max_length=20,unique=True,blank=False,verbose_name="Identificativo boa",help_text='Enter field boaXX')
group_id = models.ForeignKey('Group.auth_group', on_delete=models.SET_NULL, null=True)
def __str__(self):
"""String for representing the Model object."""
return self.Name
class Meta:
ordering = ['Name']
verbose_name_plural = "Boe"
def get_absolute_url(self):
"""Returns the url to access a particular author instance."""
return reverse('listaboe', args=[str(self.id)])
If you need to have a foreign key to Group, you can add something like:
group = models.ForeignKey(Group, related_name="boes", on_delete=models.SET_NULL)
Currently, you are using "Group.auth_group" rather than Group in your group related foreign key field.

Retrieving all database objects and its related objects Django

I am currently learning Django, and I am finding it a bit difficult wrapping my head around the ManyToMany fields. I am using an intermediate model to manage my relationships.
I have three models; Ticket, User, and TicketUserRelation.
I want to be able to query the ticket model, and retrieve both its corresponding user objects and the ticket object. How would I go about doing this?
In Laravel I would do something along the lines of
Ticket::where('id', '1')->with('contributors')
But I can't really figure out how to do this in Django
The models:
class User(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Ticket(models.Model):
contributors = models.ManyToManyField(User, through=TicketUserRelation, related_name='tickets')
name = models.CharField(max_length=50)
created_at = models.DateField()
def __str__(self):
return self.name
class TicketUserRelation(models.Model):
id = models.AutoField(primary_key=True, db_column='relation_id')
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
EDIT: I am using an intermediate model so that I can easily add things like join date later.
You don't need the TicketUserRelation model when using Django ORM. You could simply use a ForeignKey in the Ticket model, or use the ManyToManyField already defined, if one ticket can be assigned to multiple users.
class Ticket(models.Model):
# For one user, use ForeignKey
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='tickets')
# For multiple users, use ManyToManyField
contributors = models.ManyToManyField(User, related_name='tickets')
name = models.CharField(max_length=50)
created_at = models.DateField()
def __str__(self):
return self.name
You can then get all tickets for a user u with:
u.tickets.all()
Figured it out myself, using prefetch_related. I was having trouble understanding how prefetch_related works. For those that are confused too, from my understanding it works like this:
Ticket.objects.all().prefetch_related('contributors')
This returns a queryset, something along the lines of this
<QuerySet [<Ticket: Testing ticket one>, <Ticket: Testing ticket two>, <Ticket: Testing ticket three'>, <Ticket: Testing ticket four>]>
When you then access the elements in the queryset, you can then call .contributors on the object, like so:
# Get the queryset
tickets_with_contribs = Ticket.objects.all().prefetch_related('contributors')
# Print the contributors of the first ticket returned
print(tickets_with_contribs[0].contributors)
# Print the contributors of each ticket
for ticket in tickets_with_contribs:
print(ticket.contributors)
Looking back at it this should have been pretty self explanatory, but oh well.

Return all of users posts and favourites? Django

I'm creating a summary page of all of the posts the user has liked and all of the posts which the user has created.
I have two models in my db: Aircraft & Airline. The user can upload posts to either model that they prefer. I'm just slightly clueless on how to retrieve their posts?
Aircraft Model
class Aircraft(AircraftModelBase):
manufacturer = SortableForeignKey(Manufacturer)
aircraft_type = SortableForeignKey(AircraftType)
body = SortableForeignKey(Body)
engines = models.PositiveSmallIntegerField(default=1)
Airline Model
class Airline(AirlineModelBase):
fleet_size = models.PositiveSmallIntegerField()
alliance = models.CharField(max_length=100, null=True)
average_fleet_age = models.PositiveSmallIntegerField()
In my Accounts app I've made a model of the following:
class FavoritedAircraft(models.Model):
user = models.ForeignKey(User)
aircraft = models.ForeignKey(Aircraft)
def __str__(self):
return self.aircraft.name
class FavoritedAirline(models.Model):
user = models.ForeignKey(User)
airline = models.ForeignKey(Aircraft)
def __str__(self):
return self.airline.name
How do I essentially return the users favourite posts and if the user has uploaded anything, those posts as well?
Thanks for any help!
EDIT
class UploadedAircraft(models.Model):
user = models.ForeignKey(User)
aircraft = models.ForeignKey(Aircraft)
def __str__(self):
return self.aircraft.name
The favourited category you can query with something like FavoritedAirline.objects.filter(user=<the_user_here>), and it will return an iterable queryset.
However, judging for the implementation of the Aircraft and Airline models you posted, you have no field referencing who created the post (unless it's defined in your base class). If you add it there as a foreign key, just like you did in the FavoritedAirline model, you can use the same sort of query as above.

Pulling and showing data from associate table in Django rest framework

I am trying to build an API using Django Rest Framework. Which i am not familiar with. I want to know how I can pull data using references and associated tables. I have three models Users, Company and Reviews. I am storing and Auth_token in user table and I want to be able to pull reviews by a certain user by putting the auth token in the address bar.
my models are
class User(models.Model):
user_name = models.CharField(max_length=45)
email = models.CharField(max_length=255)
auth_Token = models.CharField(max_length=100,default=uuid.uuid4)
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
def __str__(self):
return self.user_name
class Company(models.Model):
company_name = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
def __str__(self):
return self.company_name
class Review(models.Model):
title = models.CharField(max_length=64)
rating = models.IntegerField(blank=False)
summary = models.TextField(max_length=10000)
ip = models.GenericIPAddressField()
company = models.ForeignKey(Company)
user = models.ForeignKey(User)
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
def __str__(self):
return self.title
I am currently able to pull reviews using following apiview:
class ReviewView(APIView):
def get(self,request):
reviews = Review.objects.all()
serializer = ReviewSerializer(reviews, many=True)
return Response(serializer.data)
and the following serilaizer:
class ReviewSerializer(serializers.ModelSerializer):
class Meta:
model = Review
fields = ('title','company', 'rating', 'summary','user')
Please ignore the indentations. However this results in me getting back the company id and user id only. I basicaly want to know two things here.
First how do i pull data where auth token is passed as the url
url(r'^reviews/(?P<auth_Token>[\w-]+)/$', ReviewView.as_view()),
and second how do i display company name and user name instead of ids. Any help would be great. Thanks
How do I filter reviews based on the user's auth token?
I will suggest using a ReadOnlyModelViewSet. It will greatly reduce your view code and allow for easy filtering. Most of the mundane and tiring code of handling requests, validating and so on has already been written in these viewsets and therefore, you can just focus on your business logic rather than server side details.
Instead of using an auth_Token in the URL param itself (eg. reviews/XXX/), I have placed it as a query param (eg. reviews/?auth_Token=XXX). The reason behind this is because the URL param itself should return a specific review resource but you need to return a list of filtered reviews mapped to one user.
from rest_framework import viewsets
class ReviewView(viewsets.ReadOnlyModelViewSet):
serializer_class = ReviewSerializer
def get_queryset(self):
"""
This function is called whenever someone tries to retrieve reviews.
You do not need to worry about serialization or handling the response
as the viewset has set that up with your specified serializer_class
"""
auth_Token = self.query_params.get("auth_Token", None)
if auth_Token: # They provided an auth token so we need to filter.
reviews = Review.objects.filter(user__auth_Token=auth_Token)
else:
reviews = Review.objects.all()
return reviews
In your urls:
url(r'^reviews/$', ReviewView.as_view({"get":"list"})),
How do I show the company name and user name in retrieved reviews and not show their ids?
You need to use a SlugRelatedField (http://www.django-rest-framework.org/api-guide/relations/#slugrelatedfield). This field allows you to replace the typical id with another attribute found in the associated table. Please see the new ReviewSerializer below:
class ReviewSerializer(serializers.ModelSerializer):
company = serializers.SlugRelatedField(read_only=True, slug_field="company_name")
user = serializers.SlugRelatedField(read_only=True, slug_field="user_name")
class Meta:
model = Review
fields = ('title','company', 'rating', 'summary','user')

Django queryset all fields of foreign key

I am looking for an elegant and efficient way to pull data out of two tables that have a one-to-one relationship.
Here are my models:
class Contact(models.Model):
name = models.CharField(max_length=100)
country = models.CharField(max_length=100)
status = models.BooleanField()
class ContactDetails(models.Model):
contact_name = models.ForeignKey(Contact)
contact_phone = models.CharField(max_length=100)
contact_fax = models.CharField(max_length=100)
and my view:
def showContact(request):
contacts = ContactDetails.objects.select_related('name').all()
print contacts.values() // debugging in console
return render(request, 'contacts/listContacts.html', { 'contacts': contacts } )
What I try to achieve is a list in my template like:
name, contact_phone, contact_fax, country, status
This again is something that must be so super simple, but I just stuck since a while with this now.
Thanks!
Fields on related models can be accessed via their given relation field.
if somedetails.contact_name.status:
print somedetails.contact_name.country