Django limit next inlinefield to first inlinefield - python

I have this model in django
from django.db import models
class ProductType(models.Model):
name = models.CharField(max_length=250)
slug = models.SlugField(unique=True)
def __unicode__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=250)
slug = models.SlugField(unique=True)
type = models.ForeignKey(ProductType, related_name='product_type')
related_products = models.ManyToManyField('self',blank=True,null=True)
description = models.TextField()
def __unicode__(self):
return self.name
What I would like to do is in the admin have the Products as tabular inline to a quote page that have multiple products. This thing is that the first selected model can be a parent to the others and therefore I would like the choices of the next elements to be sorted by the first.
this is the quote model
from django.db import models
from django.utils.translation import ugettext as _
import datetime
from products.models import Product
from customers.models import Customer
class Quote(models.Model):
quoteid = models.IntegerField(_('Quote ID'), max_length=8, unique=True, default=number)
slug = models.SlugField(unique=True,default=number)
add_date = models.DateTimeField(auto_now_add=True)
customer = models.ForeignKey(Customer, related_name='quote_customer',blank = True, null = True)
product = models.ManyToManyField(Product, related_name='quote_product')
def __unicode__(self):
return str(self.quoteid)
and the admin part
from django.contrib import admin
from quotes.models import Quote
class ProductInline(admin.TabularInline):
model = Quote.product.through
extra = 3
class QuoteAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('quoteid',)}
fieldsets = (
(('Quote'), {'fields': ('slug','quoteid','customer',)}),
)
list_display = ('quoteid','customer','add_date',)
inlines = [ ProductInline]
admin.site.register(Quote,QuoteAdmin)
I know this is quite tricky and I have tried many ways but I have not found a solution that works. I have tried with formfield_for_manytomany but I can't fully grasp how to return the first tabularinline object as the input for the queryset.
If someone have a link that explains a method to do this I would be grateful.

Related

Filter_horizontal not save django admin 4x

I'm starting a project in django 4.1. and I run into this problem:
many to many relationship: I have a field of this type that is required, and everything is fine, but when I use the filter_horizontal it does not let me insert the chosen value, it tells me that it is required, however I am selecting values
Admin.py:
from django.contrib import admin
from .models import *
from django.contrib.auth.models import User
class CatalejoAdmin(admin.ModelAdmin):
filter_horizontal = ('tematicas',)
admin.site.register(Catalejo, CatalejoAdmin)
admin.site.register(Tematicas)
Model:
from django.db import models
from django.contrib.auth.models import User
class Tematicas(models.Model):
tematica = models.CharField(max_length=500)
fecha = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(User,null=True , default=User, editable=False, on_delete=models.DO_NOTHING)
class Meta:
ordering = ["tematica"]
verbose_name_plural = "Temática"
def __str__(self):
return self.tematica
class Catalejo(models.Model):
fecha = models.DateField()
titulo = models.CharField(max_length=500)
tematicas = models.ManyToManyField(Tematicas, related_name='Temáticas')
author = models.ForeignKey(User,null=True , default=User, editable=False, on_delete=models.DO_NOTHING)
fichero = models.FileField(upload_to='gestores/%Y/%m/%d', null=True, blank=True)
class Meta:
ordering = ["fecha"]
verbose_name_plural = "Catalejo"
def Tematicas(self):
return ",\n".join([p.tematica for p in self.tematicas.all()])
def dehydrate_full_title(self, Tematicas):
return '%s by %s' % (Tematicas.tematica)
enter image description here

One to Many field in Model of Django

I am creating a model in Django, but quite confuse about the type of field should i take:
Problem: I have to access multiple domains in one web classification,
advice me please how do i make these field relationship so that if I
try to get one web classification details then it will also contain list
of related domain in that as well.
Model.py:
class WebClassification(models.Model):
vendor_id = models.ForeignKey(Vendor, on_delete=models.CASCADE, default=None, null=True)
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=100)
description = models.CharField(max_length=1000)
domain_name = models.[what type i take here]
def __str__(self):
return self.name
Domain.py
class Domain(models.Model):
id = models.IntegerField()
domain_name = models.CharField(max_length=200)
def __str__(self):
return self.domain_name
If each web classification should include a list of related domain then you should include a ForeignKey field in the Domain model to WebClassification:
# models.py
class Domain(models.Model):
id = models.IntegerField()
web_classification = models.ForeignKey(WebClassification, on_delete=models.CASCADE)
domain_name = models.CharField(max_length=200)
def __str__(self):
return self.domain_name
And you'd create a serializer for WebClassification model:
# serializers.py
from rest_framework import serializers
from .models import Domain, WebClassification
class WebClassificationSerializer(serializers.ModelSerializer):
domains = serializers.SerializerMethodField('get_domains')
def get_domains(self, id):
return Domain.objects.filter(web_classification=id).values()
class Meta:
model = WebClassification
fields = "__all__"
And use WebClassificationSerializer in a view:
# views.py
from rest_framework import generics
from .serializers import WebClassificationSerializer
from .models import WebClassification
class WebClassificationListAPIView(generics.ListAPIView):
serializer_class = WebClassificationSerializer
queryset = WebClassification.objects.all()
You can do it in two ways. It depends if one Domain may have multiple WebClassification or just one:
# one Domain may have multiple WebClassifications
class WebClassification(models.Model):
...
domains = models.ManyToManyField("Domain")
# or
# one Domain may have one WebClassification
class Domain(models.Model):
...
web_classification = ForeignKey("WebClassification", on_delete=models.CASCADE, default=None, null=True, related_name="domains")
with both methods you can access all domains related for one WebClassification with:
web_classification = WebClassification.objects.create(...)
web_classification.domains.all()
and in template
{{ web_classification.domains.all }}

how to add a new record to a Many To Many Field

I'm working on a small project using Django / Rest Framework, I have two models ( Contact & List )
I have Many To Many field, in Contact called list.
I would like to know how can I add a record to this relation ( Many To Many Field ).
from django.db import models
# Create your models here.
class List(models.Model):
name = models.CharField(blank=False, max_length=255)
comment = models.CharField(blank=False, max_length=255)
private = models.BooleanField(default=False)
allowed = models.BooleanField(default=False)
def __str__(self):
return self.name
This is my Contact Model
from django.db import models
from django.conf import settings
from list.models import List
# Create your models here.
class Contact(models.Model):
# field variables
language_choices = (
('french', 'french'),
('english', 'english'),
)
""" Relations Between Models """
list = models.ManyToManyField(List)
I looked for a solution for a long time.
Here is my method.
models.py
class Candidate(models.Model):
skills = models.ManyToManyField(Skill, through='SkillExperience')
class SkillExperience(models.Model):
"""Skills and experiences for a candidate"""
skill = models.ForeignKey(Skill, on_delete=models.CASCADE, related_name='skill_to_candidate')
candidate = models.ForeignKey(Candidate, on_delete=models.CASCADE, related_name='candidate_to_skill')
experience = models.ForeignKey(Experience, on_delete=models.CASCADE, related_name='experience_to_candidate', default=1)
serializer.py
class CandidateSkillExperienceSerializer(serializers.ModelSerializer):
experience = ExperienceSerializer(many=False, allow_null=True)
skill = SkillSerializerLite(many=False, allow_null=False)
class Meta:
model = SkillExperience
fields = ('skill', 'experience')
class CandidateSerializer(serializers.ModelSerializer):
candidate_to_skill = CandidateSkillExperienceSerializer(many=True, required=False, allow_null=True)

Django Can i fill automatically list_display

I'm trying fill automatically my list_display on my admin Django, apparently the code works correctly, but it doesn't show nothing. This is my code
Model
class Pacient(models.Model):
name = models.CharField(
max_length=50
)
last_name = models.CharField(
max_length=50
)
id_identification = models.IntegerField()
age= models.PositiveSmallIntegerField()
gender = models.ForeignKey(
Gender,
on_delete=models.CASCADE
)
blood_type = models.ForeignKey(
BloodType,
on_delete=models.CASCADE
)
def __str__(self):
return self.name
Admin.py
from django.contrib import admin
from .models import Pacient
class PacientAdmin(admin.ModelAdmin):
list_display=()
x = Pacient.objects.values()
def some(self):
for k in self.x:
k = k.keys()
self.list_display=(tuple(k))
print (self.list_display)
return self.list_display
admin.site.register(Pacient,PacientAdmin)
You need to call the some function in list_display - also the method of the class is used differently. This code snipped should work and show your Pacient data in the list_display and also "test" in every line:
from django.contrib import admin
from .models import Pacient
#admin.register(Pacient)
class PacientAdmin(admin.ModelAdmin):
list_display=["name", "last_name", "age", "some",]
def some(self, obj):
return "test"

How the updating of m2m fields are working? Django Rest Framework

I have code where Product model has M2M field Comment model. I made methods in views.py for getting Product by id and all objects of Product, but there's problem with updating it. I can't fully understand how to update Product comments field. I already tried a lot of different answers and ideas, but nothing helps me. I'm using PUT method for update.
My main questions:
Where and how target Product id in order to update comments field in it?
After I find Product by it's id how I can update M2M field comments in it?
I tried:
Completely Lost: Many To Many with Serializers and Update in Django Rest Framework
Doesn't work at all, screams for 'collections.OrderedDict' object has no attribute 'id'
Django Rest update many to many by id
It's making PrimaryKeyRelatedField which is not correct for me.
How to update many to many Django REST?
Not enough information in answer, got stuck on it.
I read, but found no usefull information on my problem
products/models.py
from django.db import models
from comments.models import Comment
# Create your models here.
class Product(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=150, blank=True)
description = models.TextField(default="No description")
category = models.CharField(max_length=255, blank=True)
price = models.DecimalField(default=100, max_digits=15, decimal_places=2, blank=True)
photo_one = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, null=True)
photo_two = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, null=True)
photo_three = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, null=True)
photo_four = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True, null=True)
is_popular = models.BooleanField(default=False)
is_hit = models.BooleanField(default=False)
has_sale = models.IntegerField(default=0)
comments = models.ManyToManyField(Comment, blank=True)
def __str__(self):
return self.name
comments/models.py
import uuid
from django.db import models
# Create your models here.
class Comment(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
username = models.CharField(max_length=255, default="default")
text = models.TextField()
rating = models.IntegerField()
def __string__(self):
return self.username
products/serializers.py
class ProductSerializer(serializers.ModelSerializer):
comments = CommentSerializer(many=True)
class Meta:
model = Product
fields = '__all__'
def update(self, instance, validated_data):
submitted_comments = validated_data.get('comments')
if submitted_comments:
for comment in submitted_comments:
comment_instance = Comment.objects.get(id=comment.id)
instance.children.add(comment_instance)
instance.save()
return instance
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ('id', 'username', 'text', 'rating')
products/views.py
import django_filters
from rest_framework import status
from rest_framework.generics import ListAPIView, RetrieveUpdateAPIView
from rest_framework.response import Response
from .models import Product
from .pagination import CustomPagination
from .serializers import ProductSerializer
class GetProductById(RetrieveUpdateAPIView):
serializer_class = ProductSerializer
filter_class = ProductFilter
queryset = Product.objects.all()
def get_product(self, pk):
try:
product = Product.objects.get(pk=pk)
except Product.DoesNotExist:
content = {
'status': 'Not Found'
}
return Response(content, status=status.HTTP_404_NOT_FOUND)
return product
def get(self, request, pk):
product = self.get_product(pk)
serializer = ProductSerializer(product)
return Response(serializer.data, status=status.HTTP_200_OK)
class ProductFilter(django_filters.FilterSet):
product_id = django_filters.UUIDFilter(name='id')
class Meta:
model = Product
fields = ['id']
class GetProducts(ListAPIView):
serializer_class = ProductSerializer
pagination_class = CustomPagination
def get_queryset(self):
products = Product.objects.all()
return products
def get(self, request):
products = self.get_queryset()
paginate_queryset = self.paginate_queryset(products)
serializer = self.serializer_class(paginate_queryset, many=True)
return self.get_paginated_response(serializer.data)
*products/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('api/products/', views.GetProducts.as_view(), name='get_products'),
path('api/product/<pk>/', views.GetProductById.as_view(), name='get_put_product')
]
I expect successful target by Product id and finding product.comments field
I expect successful adding new Comment to Product in it's comments field

Categories

Resources