I want to edit the cuisines associated with a dish on the dish panel in django admin. I am trying to use InlineModelAdmin. The problem is that I can edit the DishCuisinesMap objects but not the cuisines object.
Here is the screenshot:
This is my models.py:
class Cuisines(models.Model):
cuisine_id = models.IntegerField(primary_key=True)
cuisine_mtom = models.ManyToManyField('DishInfo', through='DishCuisinesMap')
name = models.TextField()
cuisine_sf_name = models.TextField()
type = models.IntegerField()
insert_time = models.DateTimeField()
update_time = models.DateTimeField()
class Meta:
managed = False
db_table = 'cuisines'
class DishCuisinesMap(models.Model):
dish = models.ForeignKey('DishInfo', on_delete=models.PROTECT,
related_name='dcm_dish')
cuisine = models.ForeignKey(Cuisines, on_delete=models.PROTECT,
related_name='dcm_cuisine')
insert_time = models.DateTimeField()
update_time = models.DateTimeField()
class Meta:
managed = False
db_table = 'dish_cuisines_map'
unique_together = (('dish', 'cuisine'),)
class DishInfo(models.Model):
dish_id = models.BigIntegerField(primary_key=True)
bid = models.ForeignKey(Brands, on_delete=models.PROTECT, db_column='bid',
related_name='dinfo_brand')
name = models.TextField()
is_live = models.IntegerField()
veg_nonveg_ind = models.SmallIntegerField(blank=True, null=True)
sf_name = models.TextField()
descr = models.TextField(blank=True, null=True)
expert_tag = models.TextField(blank=True, null=True)
special_desc = models.TextField(blank=True, null=True)
reco_percent = models.IntegerField(blank=True, null=True)
one_liner = models.TextField(blank=True, null=True)
nutrition = JSONField()
insert_time = models.DateTimeField()
update_time = models.DateTimeField()
images = ArrayField(models.TextField())
class Meta:
managed = False
db_table = 'dish_info'
unique_together = (('bid', 'name'), ('bid', 'sf_name'),)
def __unicode__(self):
brand_name = self.bid.name
return self.name
and this is my admin.py:
class CityDishFilter(admin.SimpleListFilter):
title = ('city name')
parameter_name = 'city_id'
def lookups(self, request, model_admin):
list_of_cities = list()
queryset = Cities.objects.all()
for city in queryset:
list_of_cities.append(
(str(city.city_id), city.name)
)
return list_of_cities
def queryset(self, request, queryset):
query_params = request.GET
if self.value():
city_query = DelLocations.objects.filter(city__city_id=self.value())\
.values('del_id')
loc_query = DelLocationsMapping.objects.filter(del_loc__in=
city_query).values('plot')
dopm_query = DishOutletPlatMapping.objects.filter(plot__in
=loc_query).values('dish')
final_query = DishInfo.objects.filter(dish_id__in=dopm_query)
if 'veg_nonveg_ind' in query_params:
final_query = final_query.filter(veg_nonveg_ind=query_params.get('veg_nonveg_ind'))
if 'is_live' in query_params:
final_query = final_query.filter(is_live=query_params.get('is_live'))
return final_query
return queryset
class BrandDishFilter(admin.SimpleListFilter):
title = ('brand name')
parameter_name = 'brand_id'
def lookups(self, request, model_admin):
query_params = request.GET
list_of_brands = list()
if 'city_id' in query_params:
city_query = DelLocations.objects.filter(city__city_id=query_params.get('city_id'))\
.values('del_id')
loc_query = DelLocationsMapping.objects.filter(del_loc__in=
city_query).values('plot')
dopm_query = DishOutletPlatMapping.objects.filter(plot__in
=loc_query).values('dish')
dish_query = DishInfo.objects.filter(dish_id__in=dopm_query).\
values('bid').distinct()
brand_query = Brands.objects.filter(bid__in=dish_query).order_by('name')
for brand in brand_query:
list_of_brands.append(
(str(brand.bid), brand.name)
)
return list_of_brands
else:
brand_query = Brands.objects.all().order_by('name')
for brand in brand_query:
list_of_brands.append(
(str(brand.bid), brand.name)
)
return list_of_brands
def queryset(self, request, queryset):
if 'brand_id' in request.GET:
queryset = queryset.filter(bid=self.value())
return queryset
return queryset
class DishCuisinesInline(admin.TabularInline):
model = DishCuisinesMap
extra = 1
class CuisinesAdmin(admin.ModelAdmin):
inlines = [DishCuisinesInline,]
fields = ("name", "cuisine_sf_name", "type")
class DishInfoAdmin(admin.ModelAdmin):
list_select_related = ('bid',)
list_display = ('name', 'brand_name')
fieldsets = (
(None, {'fields': ('name', 'sf_name', 'is_live', 'veg_nonveg_ind',
'one_liner',
)
}
),
('Advanced options', {'classes': ('collapse',),
'fields': ('descr', 'images')
}
)
)
search_fields = ['name', 'bid__name']
list_filter = ('veg_nonveg_ind', 'is_live', CityDishFilter, BrandDishFilter) #, 'bid__name'
inlines = [DishTimingsInline, DishCuisinesInline]
# changing the size of the text fields:
formfield_overrides = {
models.TextField: {'widget': Textarea(
attrs = {'rows': 4,
'cols': 50})
},
}
def brand_name(self, obj):
return obj.bid.name
admin.site.register(DishInfo, DishInfoAdmin)
admin.site.register(Cuisines, CuisinesAdmin)
The django docs here say that membership objects can be edited from Person or the Group detail pages, but what is way to edit the group from the person details page?
In my case I need a way to edit the cuisines from the dish page , I am pretty new to django. Any help is greatly appreciated.
Related
I have a post model that represents a normal post with images and possibly a video. I have a post reply model that represents comments or replies to a post.
Here is the models.py file:
class Category(models.Model):
name = models.CharField(max_length=100, verbose_name="name")
slug = AutoSlugField(populate_from=["name"])
description = models.TextField(max_length=300)
parent = models.ForeignKey(
"self", on_delete=models.CASCADE, blank=True, null=True, related_name="children"
)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="created at")
updated_at = models.DateTimeField(auto_now=True, verbose_name="updated at")
class Meta:
verbose_name = "category"
verbose_name_plural = "categories"
ordering = ["name"]
db_table = "post_categories"
def __str__(self):
return self.name
def get_absolute_url(self):
return self.slug
def video_directory_path(instance, filename):
return "{0}/posts/videos/{1}".format(instance.user.id, filename)
def post_directory_path(instance, filename):
return "posts/{0}/images/{1}".format(instance.post.id, filename)
def reply_directory_path(instance, filename):
return "replies/{0}/images/{1}".format(instance.reply.id, filename)
def reply_videos_directory_path(instance, filename):
return "{0}/posts/{1}/replies/{2}/videos/{3}".format(instance.user.id, instance.post.id, instance.reply.id, filename)
class Post(models.Model):
EV = "Everybody"
FO = "Followers"
FR = "Friends"
AUDIENCE = [
(EV, "Everybody"),
(FO, "Followers"),
(FR, "Friends"),
]
category = models.ForeignKey(Category, on_delete=models.SET_DEFAULT, default=1)
body = models.TextField("content", blank=True, null=True, max_length=5000)
slug = AutoSlugField(populate_from=["category", "created_at"])
video = models.FileField(upload_to=video_directory_path, null=True, blank=True)
can_view = models.CharField(max_length=10, choices=AUDIENCE, default=EV)
can_comment = models.CharField(max_length=10, choices=AUDIENCE, default=EV)
user = models.ForeignKey(
User, on_delete=models.CASCADE, verbose_name="user", related_name="user"
)
published = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = "post"
verbose_name_plural = "posts"
db_table = "posts"
ordering = ["created_at"]
def __str__(self):
return self.body[0:30]
def get_absolute_url(self):
return self.slug
class PostImage(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="images")
image = models.FileField(
upload_to=post_directory_path, default="posts/default.png", null=True
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = "post_images"
ordering = ["post"]
def __str__(self):
return self.post
def image_tag(self):
return mark_safe(
'<img src="/storage/%s" width="50" height="50" />' % (self.image)
)
image_tag.short_description = "Image"
class Reply(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
video = models.FileField(
upload_to=reply_videos_directory_path, null=True, blank=True
)
body = models.TextField(max_length=256, default=None)
parent = models.ForeignKey(
"self", on_delete=models.CASCADE, null=True, blank=True, related_name="replies"
)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Created at")
updated_at = models.DateTimeField(auto_now=True, verbose_name="Updated at")
class Meta:
verbose_name = "post reply"
verbose_name_plural = "post replies"
db_table = "post_reply"
def __str__(self):
return self.reply[0:30]
I have the following serializers to deal with the posts and the replies:
class PostImageSerializer(serializers.ModelSerializer):
class Meta:
model = PostImage
fields = ["id", "image", "post"]
extra_kwargs = {
"post": {"required": True},
}
class PostSerializer(serializers.ModelSerializer):
images = PostImageSerializer(many=True, read_only=True, required=False)
profile = serializers.SerializerMethodField()
class Meta:
model = Post
fields = [
"id",
"can_view",
"can_comment",
"category",
"body",
"images",
"video",
"profile",
"published",
"created_at",
"updated_at",
]
depth = 1
def get_profile(self, obj):
profile_obj = Profile.objects.get(id=obj.user.profile.id)
profile = ShortProfileSerializer(profile_obj)
return profile.data
def create(self, validated_data):
user = User.objects.get(id=self.context['request'].data.get('user'))
category = Category.objects.get(id=self.context['request'].data.get('category'))
new_post = Post.objects.create(**validated_data, category=category, user=user)
images = dict((self.context['request'].FILES).lists()).get('images', None)
if images:
for image in images:
PostImage.objects.create(
image=image, post=new_post
)
return new_post
def update(self, id):
breakpoint()
post = Post.object.all().filter(id=id)
class ReplyImageSerializer(serializers.ModelSerializer):
class Meta:
model = ReplyImage
fields = ["id", "image", "reply"]
extra_kwargs = {
"reply": {"required": True},
}
class ReplySerializer(serializers.ModelSerializer):
images = ReplyImageSerializer(many=True, read_only=True, required=False)
profile = serializers.SerializerMethodField()
post_images = serializers.SerializerMethodField(many=True)
class Meta:
model = Reply
fields = [
"id",
"post",
"post_images",
"video",
"images",
"body",
"parent",
"profile",
"created_at",
"updated_at",
]
depth = 1
def get_profile(self, obj):
profile_obj = Profile.objects.get(id=obj.user.profile.id)
profile = ShortProfileSerializer(profile_obj)
return profile.data
def get_post_images(self, obj):
post_obj = PostImage.objects.get(post=obj.post.id)
post_images = ShortProfileSerializer(post_obj)
return post_images.data
def create(self, validated_data):
new_reply = Reply.objects.create(**validated_data)
images = dict((self.context['request'].FILES).lists()).get('images', None)
if images:
for image in images:
ReplyImage.objects.create(
image=image, reply=new_reply
)
return new_reply
I use the following view to see a specific reply to a post but the related images are missing and I would like to get the related images into the endpoint. I would also like to get the category name and display that instead of the id, but images for now are more important.
I have added a serializer method field to the reply serializer to get the post images into the end point and it gets the images but it gives me an error:
get() returned more than one PostImage -- it returned 4!
Is there something I can do to get multiple objects from a serializer method field, to include in the endpoint or should I use a different approach?
Also how can I get the post category name instead of the ID?
Thank you
Use filter() method instead of get(), and pass the resulting QuerySet object to the serializer class with many=True
class ReplySerializer(serializers.ModelSerializer):
...
post_images = serializers.SerializerMethodField()
class Meta:
model = Reply
fields = [
"...",
"post_images",
]
depth = 1
def get_post_images(self, obj):
images = PostImage.objects.filter(post=obj.post.id)
serializer = PostImageSerializer(images, many=True)
return serializer.data
I tried to make method(location_item) that shows item by region.
And I want to implement the 'gu, dong' field(in location model) with multiple choices.
so, wrote this method code. but filtering doesn't work..
This shows all item objects, not just the objects I want.
TypeError: Field 'id' expected a number but got <Item: 애니원모어 원피스입니다!>.
[13/Aug/2022 15:01:07] "GET /item_post/location/location_item/ HTTP/1.1" 500 152955
I don't know what sholud i do.
please help me...
models.py
class Item(models.Model):
user_id = models.ForeignKey(User, related_name='item_sets', on_delete=models.CASCADE)
category_id = models.ForeignKey(Category, related_name='item_sets', on_delete=models.DO_NOTHING)
description = models.TextField()
feature = models.TextField()
product_defect = models.TextField()
size = models.CharField(max_length=6)
wear_count = models.IntegerField()
price = models.IntegerField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.description
class Location(models.Model):
city = models.CharField(max_length=10)
gu = models.CharField(max_length=10)
dong = models.CharField(max_length=10)
def __str__(self):
return self.city+" "+self.gu+" "+self.dong
class LocationSet(models.Model):
item_id = models.ForeignKey(Item, on_delete=models.CASCADE, related_name='location_sets')
location_id = models.ForeignKey(Location, on_delete=models.CASCADE, related_name='location_sets')
serializers.py
class ItemSerializer(serializers.ModelSerializer):
photos = PhotoSerializer(source='photo_sets', many=True, read_only=True)
style_photos = StylePhotoSerializer(source='style_photo_sets', many=True, read_only=True)
class Meta:
model = Item
fields = '__all__'
class LocationSerializer(serializers.ModelSerializer):
class Meta:
model = Location
fields = '__all__'
class LocationSetSerializer(serializers.ModelSerializer):
class Meta:
model = LocationSet
fields = '__all__'
views.py
class ItemViewSet(ModelViewSet):
queryset = Item.objects.all()
serializer_class = ItemSerializer
filter_backends = [SearchFilter, OrderingFilter]
search_fields = ['description'] # ?search=
ordering_fields = ['-created_at'] # ?ordering=
ordering = ['-created_at']
# here
#action(detail=False, methods=['GET'])
def location_item(self, request):
locations = Location.objects.all()
city = request.GET.get('city', None)
gu = request.GET.getlist('gu', None) # multiple choices
dong = request.GET.getlist('dong', None) # multiple choices
print(city, " ", gu, " ", dong) # > None [] [] (upper codes not work..)
if city:
locations = locations.filter(city=city)
if gu:
locations = locations.filter(gu__in=gu).distinct()
if dong:
locations = locations.filter(dong__in=dong).distinct()
location_ids = []
for i in locations:
location_ids.append(i.id)
locationsets = LocationSet.objects.filter(location_id__in=location_ids)
item_ids = []
for i in locationsets:
item_ids.append(i.item_id)
serializer = self.get_serializer(item_ids, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
To create method that shows items by region.
what sholud i do?
I think the last lines of code are wrong.
...
#action(detail=False, methods=['GET'])
def location_item(self, request):
...
# here I changed the last four lines
item_ids = [x.item_id for x in locationsets]
serializer = self.get_serializer(item_id__id__in = item_ids, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
Here is my model.py :
class MireilleUser(models.Model):
created = models.DateTimeField( blank=True, editable=False,default=timezone.now)
modified = models.DateTimeField( blank=True,default=timezone.now)
uuid = models.CharField(blank=True, max_length=48,default='')
firebase_id = models.CharField(max_length=256)
def save(self, *args, **kwargs):
""" On save, update timestamps """
if not self.id:
self.created = timezone.now()
self.modified = timezone.now()
if not self.uuid:
self.uuid = str(uuid.uuid4().hex) + str(random.randint(1000, 9999))
return super(MireilleUser, self).save(*args, **kwargs)
class MireilleAppSubscription(models.Model):
ACTIVE = 'AC'
SOPHOMORE = 'SO'
JUNIOR = 'JR'
SENIOR = 'SR'
GRADUATE = 'GR'
STATUS_VALUE = [
(ACTIVE, 'Active'),
('SO', 'Sophomore'),
('JR', 'Junior'),
('SR', 'Senior'),
('GR', 'Graduate'),
]
STRIPE = 'ST'
GOOGLE = 'GO'
APPLE = 'AP'
PLATFORM_VALUE = [
(STRIPE, 'STRIPE'),
(GOOGLE, 'GOOGLE'),
(APPLE, 'APPLE'),
]
created = models.DateTimeField( blank=True, editable=False,default=timezone.now)
modified = models.DateTimeField( blank=True,default=timezone.now)
uuid = models.CharField(blank=True, max_length=48,default='')
mireille_user = models.ForeignKey(MireilleUser,on_delete=models.PROTECT)
date_begin = models.DateTimeField(blank=True, editable=True, default=timezone.now)
stripe_client_id = models.CharField(blank=True, max_length=48,default='')
platform = models.CharField(blank=True, max_length=2,choices=PLATFORM_VALUE)
expected_end_time = models.DateTimeField(blank=True, editable=True, default=(timezone.now()+timezone.timedelta(days=8)))
is_free = models.BooleanField(default=False)
is_vip = models.BooleanField(default=False)
promo_code = models.CharField(blank=True, max_length=128, default='')
status = models.CharField(max_length=2,
choices=STATUS_VALUE,
default=ACTIVE)
def save(self, *args, **kwargs):
""" On save, update timestamps """
if not self.id:
self.created = timezone.now()
self.modified = timezone.now()
if not self.uuid:
self.uuid = str(uuid.uuid4().hex) + str(random.randint(1000, 9999))
return super(MireilleAppSubscription, self).save(*args, **kwargs)
And here is my admin.py :
class MireilleUser_Admin(admin.ModelAdmin):
list_display = [field.name for field in MireilleUser._meta.get_fields()]
search_fields = [field.name for field in MireilleUser._meta.get_fields()]
actions = [
export_as_csv_action(
"CSV Export",
fields=[field.name for field in MireilleUser._meta.get_fields()],
)
]
class MireilleAppSubscription_Admin(admin.ModelAdmin):
list_display = [field.name for field in MireilleAppSubscription._meta.get_fields()]
search_fields = [field.name for field in MireilleAppSubscription._meta.get_fields()]
actions = [
export_as_csv_action(
"CSV Export",
fields=[field.name for field in MireilleAppSubscription._meta.get_fields()],
)
admin.site.register(MireilleUser, MireilleUser_Admin)
admin.site.register(MireilleAppSubscription, MireilleAppSubscription_Admin)
but in the admin when i click on Mireille User on the admin i have :
AttributeError at /admin/AppUser/mireilleuser/
Unable to lookup 'mireilleappsubscription' on MireilleUser or MireilleUser_Admin
I don't understand why because the foreignkey is in MireilleAppSubscription to MireilleUser and not MireilleUser To MireilleAppSubscription
i doubt that there is something in my way of using meta fields for genrating the admin.
Regards
The is because of Django creating a reverse relation--(Django What is reverse relationship?) named mireilleappsubscription and which is not a actual field
I would suggest using the list_display and search_fields by specifying each field one-by-one
class MireilleUser_Admin(admin.ModelAdmin):
list_display = ["created", "modified", "ect"]
search_fields = ["created", "modified", "etc"]
OR
If you want just to igore the error, remove the mireilleappsubscription field from the list as,
fields = [field.name for field in MireilleUser._meta.get_fields()]
fields.remove("mireilleappsubscription")
class MireilleUser_Admin(admin.ModelAdmin):
list_display = fields
search_fields = fields
I have a model called group and another called group membership. What I'm trying to do is return a seperate string, for one of my fields in my form.
It displays correctly in the front end but when writing to the database it's all in one string. All im trying to do is get the group_name and cut out the rest of the string when writing to the database.
I'm aiming for a way to return more then one value, because i need to grab company and department later on from that same model.
My Model
# Group #
#########
class Group(models.Model):
created_by = models.ForeignKey('auth.User', related_name='group_created_by')
id = models.AutoField(primary_key=True)
company = models.ForeignKey(Company)
department = models.ForeignKey(Department)
group_name = models.CharField(max_length=100)
role = models.CharField(max_length=100)
status = models.CharField(max_length=8)
created_date = models.DateTimeField(default=timezone.now)
modified_date = models.DateTimeField(blank=True, null=True)
modified_by = models.ForeignKey('auth.User',
related_name='group_modified_by',
blank=True, null=True)
def create(self):
self.save()
def __str__(self):
return '{}{}{}'.format(self.company, self.department, self.group_name)
My Form
# Group Name #
##############
class GroupNameModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return '{}'.format(obj.group_name)
# Group Membership #
####################
class GroupMembershipForm(forms.ModelForm):
options = (('Enabled', 'Enabled',), ('Disabled', 'Disabled'))
member_id = forms.CharField(
widget=forms.TextInput(attrs={'class': 'form-control'})
)
company = forms.ModelChoiceField(
queryset=Company.objects.filter(status='Enabled'),
widget=forms.Select(attrs={'class': 'form-control'}),
empty_label=''
)
department = forms.ModelChoiceField(
queryset=Department.objects.filter(status='Enabled'),
widget=forms.Select(attrs={'class': 'form-control'}),
empty_label=''
)
group_name = GroupNameModelChoiceField(
queryset=Group.objects.filter(status='Enabled'),
widget=forms.Select(attrs={'class': 'form-control'}),
empty_label=''
)
user_id = forms.ModelChoiceField(
queryset=Person.objects.filter(status='Enabled'),
widget=forms.Select(attrs={'class': 'form-control'}),
empty_label=''
)
full_name = forms.CharField(
widget=forms.TextInput(attrs={'class': 'form-control'}),
)
status = forms.CharField(
widget=forms.Select(
attrs={'class': 'form-control'},
choices=options
)
)
class Meta:
model = GroupMembership
fields = ('member_id', 'company', 'department', 'group_name',
'user_id', 'full_name', 'status')
# Group #
#########
class Group(models.Model):
created_by = models.ForeignKey('auth.User', related_name='group_created_by')
id = models.AutoField(primary_key=True)
company = models.ForeignKey(Company)
department = models.ForeignKey(Department)
group_name = models.CharField(max_length=100)
role = models.CharField(max_length=100)
status = models.CharField(max_length=8)
created_date = models.DateTimeField(default=timezone.now)
modified_date = models.DateTimeField(blank=True, null=True)
modified_by = models.ForeignKey('auth.User',
related_name='group_modified_by',
blank=True, null=True)
def create(self):
self.save()
# Please rename to something sensible
#property
def get_special_combination_value(self):
return '{}{}{}'.format(self.company, self.department, self.group_name)
def __str__(self):
return self.group_name
To use the #property:
from <yourapp>.models import Group
obj = Group()
# following line will print the special string
obj.get_special_combination_value
The property value can also be used in django admin as:
class GroupAdmin(admin.ModelAdmin):
list_display = ('get_special_combination_value',)
admin.site.register(Group, GroupAdmin)
I can't update my object within nested object field. In here I can't update name from Movie model. Here is my model.py:
class Movie(models.Model):
name = models.CharField(max_length=800, unique=True)
imdb_rating = models.IntegerField(null=True)
movie_choice = (
('Act', 'Action'),
...........
)
movie_type = models.CharField(max_length=3, choices=movie_choice)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Hiren(models.Model):
movie = models.ForeignKey(Movie)
watched_full = models.BooleanField(default=True)
rating = models.IntegerField()
source = models.CharField(max_length=500, null=True)
watched_at = models.DateField()
quality_choice = (
..................
)
video_quality = models.CharField(max_length=3, choices=quality_choice)
created_at = models.DateField(auto_now_add=True)
updated_at = models.DateField(auto_now=True)
and serializer.py
class MovieSerializer(serializers.ModelSerializer):
class Meta:
model = Movie
fields = '__all__'
class HirenSerializer(serializers.ModelSerializer):
movie = MovieSerializer()
class Meta:
model = Hiren
fields = ('movie', 'id', 'watched_full', 'rating', 'source', 'video_quality', 'watched_at')
def update(self, instance, validated_data):
instance.movie.name = validated_data.get('movie.name', instance.movie.name)
instance.watched_full = validated_data.get('watched_full', instance.watched_full)
instance.rating = validated_data.get('rating', instance.rating)
instance.source = validated_data.get('source', instance.source)
instance.video_quality = validated_data.get('video_quality', instance.video_quality)
instance.watched_at = validated_data.get('watched_at', instance.watched_at)
instance.save()
return instance
You didn't call save on related object
def update(self, instance, validated_data):
instance.movie.name = validated_data.get('movie', {}).get('name') or instance.movie.name
instance.watched_full = validated_data.get('watched_full', instance.watched_full)
instance.rating = validated_data.get('rating', instance.rating)
instance.source = validated_data.get('source', instance.source)
instance.video_quality = validated_data.get('video_quality', instance.video_quality)
instance.watched_at = validated_data.get('watched_at', instance.watched_at)
# here
instance.movie.save()
instance.save()
return instance