Django only want to get first row of a queryset - python

i want to display the first entry of a queryset.
i try some answers here but it does´tn work on my code example.
here is my code:
class FeatureFilmAdmin(admin.ModelAdmin):
inlines = [
QuoteAndEffortSetInLine,
ProjectCompanySetInLine,
VendorVFXSetInLine,
VendorSetInLine,
StaffListSetInLine,
]
list_display = ["title", "program_length", "get_production_company_name"]
def get_production_company_name(self, Featurefilm):
return FeatureFilm.objects.filter(pk=Featurefilm.id).values(
"projectcompanyset__production_company__name"
)
so i actually want to display the production_company, from the first table of ProjectCompanySet in the admin as list_display.
so i actually want to display the production_company, from the first table of ProjectCompanySet in the admin as list_display. but with the code above, it will show me all production_company, if there are multiple ProjectcompanySet. What is displayed so far is also not the production_company name but the str function and not the data field itself. Here I would need help please.
here are the models of my problem:
class CompanyOrBranch(CompanyBaseModel):
name = models.CharField(
"Firma oder Niederlassung",
max_length=60,
blank=False,
)
class FeatureFilm(ProjectBaseModel):
class Meta:
verbose_name = "Kinofilm"
verbose_name_plural = "Kinofilme"
class ProjectCompanySet(models.Model):
feature = models.ForeignKey(
FeatureFilm,
on_delete=models.CASCADE,
null=True,
blank=True,
)
production_company = models.ForeignKey(
CompanyOrBranch,
related_name="production_company",
verbose_name="Produktionsfirma",
on_delete=models.SET_NULL,
blank=True,
null=True,
)
here is the output of my admin list:

Related

Django: How to Filter Model with "where" clause to display in list admin related objects

I have 2 models that depend on each other. One is the FeatureFilm model and the other is the CompanyInvolved model.
In the FeatureFilm table I want to store movies and in the CompanyInvolved table I want to store the many companies that have contributed to a movie. The CompanyInvolved model is attached to the FeatureFilm table with a foreignkey. I want to display a column from the CompanyInvolved table in the list view of the FeatureFilm Admin Panel. I have already done that with my code. The only thing I didn't get yet is a filter that filters the CompanyInvolved table on the field company_role. I want to show only the values that have the company_role = "Produktion". oh yes I want to show only the first production company, the other rows do not play a role in the list tables view. many greetings Can someone please help? many greetings
here is my depending code:
model.py
company_role = [
("Produktion", "Produktion"),
("Co-Produktion", "Co-Produktion"),
("Kinoverleih", "Kinoverleih"),
("Sender", "Sender"),
("Weltvertrieb", "Weltvertrieb"),
]
class ProjectBaseModel(models.Model):
title = models.CharField("Titel", max_length=100, blank=False,
unique=True)
leading_postproduction_id = models.ForeignKey(
Company,
verbose_name="Federführende Postproduktion",
on_delete=models.SET_NULL,
blank=True,
null=True,
)
class FeatureFilm(ProjectBaseModel):
class Meta:
verbose_name = "Kinofilm"
class CompanyInvolved(models.Model):
feature_id = models.ForeignKey(
FeatureFilm,
on_delete=models.CASCADE,
null=True,
blank=True,
)
tv_movie_id = models.ForeignKey(
TvMovie, on_delete=models.CASCADE, null=True, blank=True
)
company_role = models.CharField(
choices=company_role,
max_length=15,
blank=True,
help_text="Produktion, Co-Produktion, Kinoverleiher, Sender,
Weltvertrieb",
)
company_involved = models.ForeignKey(
Company,
on_delete=models.SET_NULL,
null=True,
blank=True,
)
def __str__(self):
return "#" + str(self.pk)
views.py
class FeatureListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
permission_required = "project.can_access_featurefilm_list"
model = FeatureFilm
template_name = "project/feature-list.html"
def handle_no_permission(self):
return redirect("access-denied")
admin.py --- here is the code that is my problem****look to get_company_involved
#admin.register(FeatureFilm)
class FeatureFilmAdmin(admin.ModelAdmin):
inlines = [
SalesInfoSetInLine,
ContentInfoSetInLine,
CompanyInvolvedSetInLine,
]
list_display = [
"title",
"get_company_involved",
"program_length_planned",
]
def get_company_involved(self, obj):
productioncompany = (
FeatureFilm.objects.filter(pk=obj.id)
.values("companyinvolved__company_involved__name")
.first()
)
return productioncompany["companyinvolved__company_involved__name"]
get_company_involved.short_description = "Produktion"
i tried more times and solves my question. here is the solution, in get_production_involved you can see the correct query
#admin.register(FeatureFilm)
class FeatureFilmAdmin(admin.ModelAdmin):
inlines = [
SalesInfoSetInLine,
CompanyInvolvedSetInLine,
]
list_display = [
"title",
"get_production_involved",
]
def get_production_involved(self, obj):
production_company = (
FeatureFilm.objects.filter(
pk=obj.id,
companyinvolved__company_role="Produktion",
companyinvolved__is_production_list=True,
)
.values_list("companyinvolved__company_involved__name")
.first()
)
if production_company:
return production_company
else:
production_company = (
FeatureFilm.objects.filter(
pk=obj.id,
companyinvolved__company_role="Produktion",
)
.values_list("companyinvolved__company_involved__name")
.first()
)
return production_company
get_production_involved.short_description = "Produktion"

Django Model Instance as Template for Another Model that is populated by Models

I'm trying to create a workout tracking application where a user can:
Create an instance of an ExerciseTemplate model from a list of available Exercise models. I've created these as models so that the user can create custom Exercises in the future. There is also an ExerciseInstance which is to be used to track and modify the ExerciseTemplate created by the user, or someone else. I'm stripping the models of several unimportant fields for simplicity, but each contains the following:
class Exercise(models.Model):
# Basic Variables
name = models.CharField(max_length=128)
description = models.TextField(null=True, blank=True)
def __str__(self):
return self.name
class ExerciseTemplate(models.Model):
# Foreign Models
workout = models.ForeignKey(
'Workout',
on_delete=models.SET_NULL,
null=True,
blank=True
)
exercise = models.ForeignKey(
Exercise,
on_delete=models.SET_NULL,
null=True,
blank=True
)
recommended_sets = models.PositiveIntegerField(null=True, blank=True)
class ExerciseInstance(models.Model):
""" Foreign Models """
exercise_template = models.ForeignKey(
ExerciseTemplate,
on_delete=models.SET_NULL,
null=True,
blank=True
)
workout = models.ForeignKey(
'Workout',
on_delete=models.SET_NULL,
null=True,
blank=True
)
""" Fields """
weight = models.PositiveIntegerField(null=True, blank=True)
reps = models.PositiveIntegerField(null=True, blank=True)
Create a WorkoutInstance from a WorkoutTemplate. The WorkoutTemplate is made up of ExerciseTemplates. But the WorkoutInstance should be able to take the WorkoutTemplate and populate it with ExerciseInstances based on the ExerciseTemplates in the WorkoutTemplate. Here are the models that I have so far:
class WorkoutTemplate(models.Model):
name = models.CharField(max_length=128)
description = models.TextField(null=True, blank=True)
date = models.DateTimeField(null=True, blank=True)
#category...
exercises = models.ManyToManyField(
Exercise,
through=ExerciseTemplate
)
def __str__(self):
return self.name
class WorkoutInstance(models.Model):
# Foreign Models
workout_template = models.ForeignKey(
'WorkoutTemplate',
on_delete=models.SET_NULL,
null=True,
blank=True
)
But this is where I get stuck. I'm not sure how to proceed. My intuition is one of the following:
I need to create a more simple architecture to do this. I'll take any suggestions.
I need to create a method within the model that solves this issue. If this is the case, I'm not sure what this would actually look like.
When you create a new WorkoutInstance object which references a given WorkoutTemplate object you get all its related ExerciseTemplate objects.
Then you just create a new object (row) for each ExerciseInstance in another model (table)
If you link your ExerciseInstance to WorkoutInstance via 'workout' you could do something like:
wt = WorkoutTemplate.get(id=1)
wi = WorkoutInstance.create(workout_template=wt)
for e in wt.exercisetemplate_set.all:
ExerciseInstance.create(exercise_template=e, workout=wi)
You can implent this in the method that creates the new WorkoutInstance or take a look at signals
https://docs.djangoproject.com/en/4.0/topics/db/optimization/#create-in-bulk

Django Rest API ManyToMany gives nothing [] in API

at the moment I try to get recipes from my API. I have a Database with two tables one is with recipes and their ids but without the ingredients, the other table contains the ingredients and also the recipe id. Now I cant find a way that the API "combines" those. Maybe its because I added in my ingredient model to the recipe id the related name, but I had to do this because otherwise, this error occurred:
ERRORS:
recipes.Ingredients.recipeid: (fields.E303) Reverse query name for 'Ingredients.recipeid' clashes with field name 'Recipe.ingredients'.
HINT: Rename field 'Recipe.ingredients', or add/change a related_name argument to the definition for field 'Ingredients.recipeid'.
Models
from django.db import models
class Ingredients(models.Model):
ingredientid = models.AutoField(db_column='IngredientID', primary_key=True, blank=True)
recipeid = models.ForeignKey('Recipe', models.DO_NOTHING, db_column='recipeid', blank=True, null=True, related_name='+')
amount = models.CharField(blank=True, null=True, max_length=100)
unit = models.CharField(blank=True, null=True, max_length=100)
unit2 = models.CharField(blank=True, null=True, max_length=100)
ingredient = models.CharField(db_column='Ingredient', blank=True, null=True, max_length=255)
class Meta:
managed = True
db_table = 'Ingredients'
class Recipe(models.Model):
recipeid = models.AutoField(db_column='RecipeID', primary_key=True, blank=True) # Field name made lowercase.
title = models.CharField(db_column='Title', blank=True, null=True, max_length=255) # Field name made lowercase.
preperation = models.TextField(db_column='Preperation', blank=True, null=True) # Field name made lowercase.
images = models.CharField(db_column='Images', blank=True, null=True, max_length=255) # Field name made lowercase.
#ingredients = models.ManyToManyField(Ingredients)
ingredients = models.ManyToManyField(Ingredients, related_name='recipes')
class Meta:
managed = True
db_table = 'Recipes'
When there is no issue it has to be in the serializer or in the view.
Serializer
class IngredientsSerializer(serializers.ModelSerializer):
# ingredients = serializers.CharField(source='ingredients__ingredients')
class Meta:
model = Ingredients
fields = ['ingredient','recipeid']
class FullRecipeSerializer(serializers.ModelSerializer):
ingredients = IngredientsSerializer(many=True)
class Meta:
model = Recipe
fields = ['title','ingredients']
View
class FullRecipesView(generics.ListCreateAPIView):
serializer_class = FullRecipeSerializer
permission_classes = [
permissions.AllowAny
]
queryset = Recipe.objects.all()
This is at the moment my output
But I want e.g. the recipe with id 0 and all the ingredients which have also recipe id 0.
I really hope that you can help me. Thank you so much!
From the doc of ForeignKey.related_name,
If you’d prefer Django not to create a backwards relation, set related_name to '+' or end it with '+'.
So, change the related_name of Ingredients.recipeid field to
class Ingredients(models.Model):
# rest of the fields
recipeid = models.ForeignKey(
'Recipe',
models.DO_NOTHING,
db_column='recipeid',
blank=True,
null=True,
related_name="ingredients_ref" # Changed the related name
)
Then, migrate the database using python manage.py makemigrations and python manage.py migrate
Then, update your FullRecipeSerializer class as,
class FullRecipeSerializer(serializers.ModelSerializer):
ingredients_forward = IngredientsSerializer(many=True, source="ingredients")
ingredients_backward = IngredientsSerializer(many=True, source="ingredients_ref")
class Meta:
model = Recipe
fields = ['title', 'ingredients_forward', 'ingredients_backward']
Note that, here I have added two fields named ingredients_forward and ingredients_backward because there existing two types of relationships between Recipe and Ingredients and I am not sure which one you are seeking.

Add parent field in django admin forms

Here are my two models:
class Provider(models.Model):
name = models.CharField(max_length=75, null=True, blank=True)
code = models.CharField(max_length=15)
provider_parent = models.ForeignKey('self', null=True, blank=True)
accounts = models.ManyToManyField('Account', blank=True)
data_types = models.ManyToManyField('DataType', blank=True,
through='ProviderDataType')
class Account(models.Model):
name = models.CharField(max_length=75, unique=True)
prefixes = models.ManyToManyField('AccountPrefix', blank=True)
Here is my admin.py
class ProviderAdmin(admin.ModelAdmin):
list_display = ('code', '__unicode__')
class AccountAdmin(admin.ModelAdmin):
list_display = ('__unicode__')
admin.site.register(Provider, ProviderAdmin)
admin.site.register(Account, AccountAdmin)
I was wondering if it is possible to have a selection of the parent provider when I try to add or update my account model and upon saving it. The Parent model has already set the account on its manytomany field
If I understood your question correctly you can use TubularInline. Like this:
class ProviderInline(admin.TabularInline):
model = Provider.accounts.through
extra = 1
class AccountAdmin(admin.ModelAdmin):
inlines = [ProviderInline,]
...

DRF Exception value: Cannot assign - it must be a instance

I know there are a bunch of questions addressing this issue, but I haven't solved it out yet. I'm using DRF for the first time and I'm working with nested serializers. My Restaurant serializer points to a Category serializer via a slug related field as it shows below
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = (
'name',
'description'
)
class RestaurantSerializer(serializers.HyperlinkedModelSerializer):
category = serializers.SlugRelatedField(
many=True,
read_only=False,
queryset=Category.objects.all(),
slug_field='name'
)
class Meta:
model = Restaurant
fields = (
'id',
'name',
'description',
'website',
'twitter',
'facebook',
'instagram',
'category'
)
I send all the necessary data to my endpoint to create a new Restaurant via jquery but I keep getting "Cannot assign "[< Category: Italian food >]": "Restaurant.category" must be a "Category" instance."
I understand I need to assign a Category object to Restaurant's category, although I don't know how to access my queryset to extract the object that matters.
Any advices on this?
Edit: This is the data I'm sending from jquery to my endpoint
{"name":"Restaurant","email":"restaurant#gmail.com","password":"1234","category":["Italian food"],"description":"Description test"}
Edit # 2 See the model definitions below
class Restaurant(models.Model):
name = models.CharField(max_length=80, null=False)
description = models.TextField(max_length=300, null=False)
email = models.EmailField(max_length=80, null=True)
password = models.CharField(max_length=60, null=False)
website = models.URLField(max_length=80, null=True)
twitter = models.CharField(max_length=60, null=True, blank=True)
facebook = models.CharField(max_length=60, null=True, blank=True)
instagram = models.CharField(max_length=60, null=True, blank=True)
category = models.ForeignKey('Category')
def __unicode__(self):
return self.name
class Category(models.Model):
name = models.CharField(max_length=80, null=False)
description = models.TextField(max_length=100, null=False)
def __unicode__(self):
return self.name
You have a ForeignKey from Restaurant to Category. That means there is only one Category for each Restaurant. But you are sending a list of category slugs, and you have many=True in the definition of the SlugRelatedField.
Your data should just be {..."category": "Italian food"...}, and you should remove the many=True.

Categories

Resources