django: how does manytomanyfield with through appear in admin? - django

As stated in the title how does manytomanyfield with through appear in the admin site?
class SchoolClass(models.Model):
id = models.AutoField(primary_key = True)
class_name = models.TextField()
level = models.IntegerField()
taught_by = models.ManyToManyField(User,related_name="teacher_teaching",through='TeachSubject')
attended_by = models.ManyToManyField(User,related_name='student_attending')
def __unicode__(self):
return self.class_name
class Meta:
db_table = 'classes'
class TeachSubject(models.Model):
teacher = models.ForeignKey(User)
class_id = models.ForeignKey(SchoolClass)
subject = models.ForeignKey(Subject)
In the admin site, for the model SchoolClass, I have a field for attending students, but not the teachers.

You should use InlineModelAdmin. Docs.
class TeachSubjectInline(admin.TabularInline):
model = TeachSubject
extra = 2 # how many rows to show
class SchoolClassAdmin(admin.ModelAdmin):
inlines = (TeachSubjectInline,)
admin.site.register(SchoolClass, SchoolClassAdmin)

Related

How to retrieve data from model that current user created and list it for another model's field in django

Let us imagine that I have two models.
First model contains curse details and user that created this course
class Course(models.Model):
course_name = models.CharField(max_length=100, null=False)
description = models.CharField(max_length=255)
user_profile = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
and my second model is:
class Lesson(models.Model):
course = models.OneToOneField(Course, on_delete=models.CASCADE) #
# inside the course I want my APIVIEW to list only the courses that current user created.
# OnetoOne relationship does not solve the problem.
status = models.CharField(choices=STATUS, null=False, default=GOZLEMEDE,max_length=20)
tariffs = models.FloatField(max_length=5,null=False,default=0.00)
continues_off = models.CharField(max_length=2)
user_profile = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
My serializers for both Models:
class LessonSerializer(serializers.ModelSerializer):
class Meta:
model = models.Lesson
fields = ('course', 'status', 'tariffs', 'continues_off', 'user_profile')
def create(self, validated_data):
lesson = models.Lesson.objects.create(
course = validated_data['course'],
status = validated_data['status'],
tariffs=validated_data['tariffs'],
continues_off=validated_data['continues_off'],
user_profile=validated_data['user_profile']
)
return lesson
class CourseSerializer(serializers.ModelSerializer):
"""Serializers Course content"""
class Meta:
model = models.Course
fields = '__all__'
def create(self,validated_data):
course = models.Course.objects.create(
course_name = validated_data['course_name'],
description=validated_data['description'],
user_profile=validated_data['user_profile']
)
return course
My Viewset:
class LessonViewset(viewsets.ModelViewSet):
model = models.Lesson
serializer_class = serializers.LessonSerializer
authentication_classes = (SessionAuthentication,)
permission_classes = (IsAuthenticated,BasePermission,)
def get_queryset(self):
user_current = self.request.user.id
return models.Lesson.objects.filter(user_profile=user_current)
How can I get the desired result. I want to get the courses for the current user and show them as a dropdown list in my API view. Just only the courses that user created should be in the dropdown list not all.
OnetoOne relationship gives all results of course table.
i think change your view code to :
def get_queryset(self,id):
return model.objects.filter(user_profile=id)
#You do not need to call it again when you put the Lesson on the model
\

fields in class Meta got invalid

models.py
class Product(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
price = models.DecimalField(decimal_places=5,max_digits= 1500)
summary = models.TextField()
featured = models.BooleanField()
def __str__(self):
return self.title
# return f'product title:{self.title}-product price:{self.price}'workok
class Meta:
ordering = ('-price',)
class Opinion(models.Model):
name = models.CharField(max_length=20)
email = models.EmailField(max_length=20)
body = models.TextField()
opinion_date = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=False)
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='opinion_set')
def __str__(self):
return f'({self.name}) add opinion about ({self.product})'
forms.py:
from django.forms import ModelForm
from .models import Product #space after from keyword
class OpinionModelForm(ModelForm):
class Meta:
model = Product
fields = ['name','email','body','product']
invalid in code line :
fields = ['name','email','body','product'] #---- NOT WORK !!!
, but if i change above code to :
fields = "__all__" # ----it is WORKing ok without any problem !!
question : what is the error? I am not need all the fields in the Product model (like active boolean field), I need only 'name','email','body','product' fields .
According to the error and the code you provided the main problem is that you made a mistake in chosing model in serializer:
class OpinionModelForm(ModelForm):
class Meta:
model = Product
fields = ['name','email','body','product']
Serializer name is OpinionModelForm and listed fields belong to Opinion so I guess you actually wanted to serialize Opinion and no Product as you defined at this line:
model = Product
Simply change it to:
model = Opinion

related objects queries django rest framework

I have the following models
class STUser(AbstractBaseUser):
email = models.EmailField(unique=True)
name = models.CharField(max_length=255)
companyname = models.CharField(max_length=200, blank=True, null=True)
...
class VenuePermissions(models.Model):
user = models.ForeignKey(STUser, on_delete=models.CASCADE)
venue = models.ForeignKey(Venue, on_delete=models.CASCADE)
signupvaildatestring = models.CharField(max_length=200, blank=True, null=True)
...
I want to grab all the STUser objects and grab all their permissions.
So what I would like is to grab all the VenuePermissions objects. And grab the user and venue object of each venuePermission
Two ways I can do this. use the VenuePermissions_set attribute on STUser but then how do I grab the venue when its just going to be a pk value?
Or focus on the VenuePermissions objects and grab the user and venue from the pk values but how?
I remember nested queries, and I kinda did one in my browse code.
here is an example:
rooms = Room.objects.filter(venue=OuterRef('pk'), sixtyroundseatingoption= True)
venuelist = venuelist.annotate(sixtyrounds=Exists(rooms))
venuelist = venuelist.filter(Q(sixtyrounds = True) | Q(fullbuyoutsixtyroundseatingoption = True))
I've done the set objects in a serializer before
Example serializer:
class RoomAndImageSerializer(serializers.ModelSerializer):
roomimage_set = RoomImageSerializer(many=True, read_only=True)
class Meta:
model = Room
fields = ('pk','name')
any help with this query would be appreciated!
So this is what I am currently trying, I will post an answer if this works:
class VenueUserList(ListAPIView):
serializer_class = VenueUserListSerializer
queryset = VenuePermissions.objects.select_related('user').select_related('venue').filter(signupvaildatestring=None)
class VenueUserListSerializer(serializers.ModelSerializer):
user = UserSerializer()
venue = VenueSerializer()
class Meta:
model = VenuePermissions
fields = ('user', 'venue', 'isvenueviewer', 'isvenueeventplanner', 'isvenueadministrator')
Here is the answer. However I still need to group venues by user. Working on that.
class VenueUserList(ListAPIView):
serializer_class = VenueUserListSerializer
queryset = VenuePermissions.objects.select_related('user').select_related('venue').filter(signupvaildatestring=None)
class VenueUserListSerializer(serializers.ModelSerializer):
user = UserSerializer()
venue = VenueSerializer()
class Meta:
model = VenuePermissions
fields = ('user', 'venue', 'isvenueviewer', 'isvenueeventplanner', 'isvenueadministrator')

Display the object related set objects in the admin

I have three models for Movie, NowShowing and UpComingMovie. NowShowing and UpComingMovie has foreignkey relationship with the Movie.
class Movie(models.Model):
name = models.CharField(max_length=254, unique=True)
synopsis = models.TextField()
release_date = models.DateField()
director = models.ManyToManyField(MovieDirector)
writer = models.ManyToManyField(MovieWriter)
actor = models.ManyToManyField(MovieActor)
censor_rating = models.PositiveIntegerField(choices=CENSOR_TYPE)
#property
def is_screening(self):
if self.nowshowing_set.all().count() > 0:
return True
else:
return False
class NowShowing(models.Model):
movie = models.ForeignKey(Movie)
show_time = models.DateTimeField()
class UpComingMovie(models.Model):
movie = models.ForeignKey(Movie)
Each three of the models can be accesed in the admin:
class MovieAdmin(admin.ModelAdmin):
list_display = ('name', 'release_date', 'censor_rating', 'is_screening')
class Meta:
model = Movie
admin.site.register(Movie, MovieAdmin)
admin.site.register(NowShowing)
admin.site.register(UpComingMovie)
The problem is that I have to go to NowShowing or UpComingMovie admin page to create/change object. Is it possible to display each movies related set fields (NowShowing or UpComingMovie) to display in the Movie object detail admin page itself, so that its related field can be created/changed from the Movie obj directly without going to NowShowing or Upcoming admin page?
Yes, it's quite possible thanks to TabularInline (or StackedInline)
class UpcomingInline(admin.TabularInline):
model = UpComingMovie
class NowShowingInline(admin.TabularInline):
model = NowShowing
class MovieAdmin(admin.ModelAdmin):
list_display = ('name', 'release_date', 'censor_rating', 'is_screening')
inlines = [UpcomingInline,NowShowingInline]
class Meta:
model = Movie

Django admin: ordering inline based on FK'd property

I've got a simple Django photography competition app that has three simple model definitions:
class Person(models.Model):
name = models.CharField(unique=True, max_length=255)
id = models.AutoField(primary_key=True)
class Meta:
db_table = u'people'
def __unicode__(self):
return self.name
class Round(models.Model):
theme = models.CharField(max_length=255)
number = models.IntegerField()
id = models.AutoField(primary_key=True)
class Meta:
db_table = u'rounds'
def __unicode__(self):
return self.season.name+" - "+self.theme
class Entry(models.Model):
rank = int
total_score = models.SmallIntegerField()
id = models.AutoField(primary_key=True)
person = models.ForeignKey(Person, db_column='person')
round = models.ForeignKey(Round, db_column='round')
A Round has multiple Entry objects, and each Entry has one Person. One Person can obviously have multiple Entrys into different Rounds.
In the admin view, I'd like to be able to select a Round and see the details of the Entry items inline. This I can do with the following:
class EntryInline(admin.TabularInline):
model = Entry
fields = ['comments','person','total_score','image']
readonly_fields = ['person','image']
extra = 0
class RoundAdmin(admin.ModelAdmin):
fields = ['theme','number']
inlines = [EntryInline]
However, this sorts the Entry seemingly arbitrarily. I can use django's new ordering keyword in the EntryInline class to specify the ordering should be on the person, but this orders by the person Id property and not their name property.
How would I order this inline on the FK'd Person.name property?
Add this in the EntryInline class:
ordering = ["person__name"]