I try to figure a clever way out for my models.
I have two models where i want the Legend to have 4 different skills(Skill Model), but I cant seem to get the fitting model relation for it
class Skill(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
title = models.CharField(max_length=100)
description = models.CharField(max_length=300)
image = models.ImageField(upload_to='skills/', blank=True, null=True)
class Legend(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
title = models.CharField(max_length=100)
description = models.CharField(max_length=1000)
image = models.ImageField(upload_to='legends/%Y/', blank=True, null=True)
skill_1 = models.(Skill, on_delete=models.SET_NULL, null=True)
skill_2 = models.OneToOneField(Skill, on_delete=models.SET_NULL, null=True)
skill_3 = models.OneToOneField(Skill, on_delete=models.SET_NULL, null=True)
skill_4 = models.OneToOneField(Skill, on_delete=models.SET_NULL, null=True)
The problem is I cant rly make a OneToOneField because it want´s a related_name for each, which would make No sense here, since they are all skills and I dont want to call for the owner (Legend) of the skill in 4 different ways
I also tried to make a legend field in the Skill model with a foreignkey on the Legend, but that didnt turned out how i wanted it to be.
thanks for the help ^.^
Moving my answer here, so I can format code
So... do it as I've said. Add FK in Skill pointing to Legend. Afterwards in your admin.py create admin class which inherits from StackedInline or TabularInline. Your file should look like this:
from django.contrib import admin
from apps.legends.models import Skill, Legend
class InlineAdminSkill(admin.TabularInline):
model = Skill
extra = 4
max_num = 4
class LegendAdmin(admin.ModelAdmin):
inlines = [InlineAdminSkill]
admin.site.register(Legend, LegendAdmin)
This should resolve problem in admin - your skill will be visible in your admin legend view. Try it out.
In your views in the other hand you just have to add a logic which uses e.g. formsets and enables you adding max 4 skills.
Related
How to make a one to many relationship in Django/Mysql?
I have an identical situation to this post, yet, my django returns errors on the admin page:
get() returned more than one order2pizza-- it returned 5!
order2pizza with that pizza already exists.
My mysql database have composite keys on a tertiary table to order and pizza to link multiple pizzas to an order.
models.py:
class Orders(models.Model):
order_id = models.AutoField(primary_key=True)
order_name = models.CharField(max_length=100, blank=True, null=True)
class Pizza(models.Model):
Pizza= models.AutoField(primary_key=True)
Pizza_name= models.CharField(max_length=50, blank=True, null=True)
class order2pizza(models.Model):
order = models.ManyToManyField(Orders, models.DO_NOTHING, )
pizza_id= models.IntegerField()
class Meta:
unique_together = (('order ', 'pizza_id'),)
A many-to-many relation can be expressed in two ways. First, you can manually specify a "join" model, like this:
class Orders(models.Model):
order_name = models.CharField(max_length=255, blank=True)
class Pizza(models.Model):
Pizza_name= models.CharField(max_length=255, blank=True)
class Order2Pizza(models.Model):
order = models.ForeignKey(Order, models.CASCADE)
pizza = models.ForeignKey(Pizza, models.CASCADE)
class Meta:
unique_together = ['order ', 'pizza']
This is useful if you want to put extra fields on the Order2Pizza model. A field named quantity would be very useful in your example.
The second option is to use a ManyToManyField. This will automatically create the join model for you:
class Orders(models.Model):
order_name = models.CharField(max_length=255, blank=True)
pizzas = models.ManyToManyField('Pizza', related_name='orders')
class Pizza(models.Model):
Pizza_name= models.CharField(max_length=255, blank=True)
In your original question you put the ManyToManyField on the Order2Pizza model, which is nonsensical.
However, the source of your bug is probably your manual inclusion of several *_id fields. Don't do that. They will always be created automatically by Django and you should never have to specify them manually. Instead, try the two options above and see how they work.
I'm still relatively new to programming, Django, and creating apps so please bear with me. I'm working on a dietary app and I'm having a hard time visualizing and understanding why my specific use case of a ManyToManyField for one of my models is not showing up in the admin console. I tried reading the Django docs for the ManyToManyField relationship but I am still having troubles understanding it, so hopefully someone can explain this to me like I am a happy golden retriever.
I have three models:
class Product(models.Model):
product_name = models.CharField(verbose_name='Product name', max_length=100)
product_description = models.TextField(verbose_name='Product description', max_length=500)
product_id = models.UUIDField(default=uuid.uuid4(), unique=True)
def __str__(self):
return self.product_name
#-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------#
class Recipe(models.Model):
recipe_name = models.CharField(verbose_name='Recipe name', max_length=100)
ingredients = models.ManyToManyField(Product, related_name='Ingredients', through='IngredientQuantity', through_fields=('recipe','ingredient'))
class Meta:
ordering = ['recipe_name']
def __str__(self):
return self.recipe_name
#-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------#
class IngredientQuantity(models.Model):
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
ingredient = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.DecimalField(verbose_name='Quantity', decimal_places=2, max_digits=99, null=False)
What I was trying to do with this was create an Intermediary with IngredientQuantity which will give me the quantity along with a selected Product that I can then associate with Recipe.
However I am not seeing the ingredients input for Recipe when I attempt to create a new entry for Recipe in the Django admin console, is this supposed to be the case?
In your app admin.py file add these lines:
from django.contrib import admin
from .models import Product, Recipe, IngredientQuantity
admin.site.register(Product)
admin.site.register(Recipe)
admin.site.register(IngredientQuantity)
Then you should see your models in your admin interface.
Hello all I am making auction website like ebay, I have this model design which has many other extra attributes model classes for different categories. But here let's take an example of a PC one which will be used for its sub-categories Desktop and Laptop.
Now the problem, I want to create ModelForm for users. For instance if user selects Desktop as their product to put on auction, how will that modelform code look like? So the Desktop respected fields are given to the user to fill from the extra_pc_attributes class? The problem is that, wouldn't it get tedious to write separate modelform for each category and also in the views.py use those as objects.
Maybe use Jsonfield instead of creating a whole EAV old-fashioned table for extra attributes? But I am new and I don't know how it will work or even if it applies to this situation.
class Categories(MPTTModel):
name = models.CharField(max_length=50, unique=True)
parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
class auction_product(models.Model):
product_name = models.CharField(max_length=64)
category = models.ForeignKey(Categories, on_delete=models.CASCADE)
date_added = models.DateField(default=timezone.now)
user = models.ManyToManyField(User, through='product_ownership', related_name='product_user')
product_bid = models.ManyToManyField(User, through='bid', related_name='product_bid')
product_comment = models.ManyToManyField(User, through='comment')
album = models.OneToOneField(ImageAlbum, related_name='product_model', on_delete=models.CASCADE)
def __str__(self):
return self.product_name
#Extra PC Attributes
class extra_pc_attributes(auction_product):
processor = models.CharField(max_length=264)
ram = models.FloatField()
brand = models.CharField(max_length=64)
motherboard = models.CharField(max_length=264)
case = models.CharField(max_length=264)
screen_size = models.FloatField()
weight = models.FloatField()
Say there is a poll app and I want a user to vote only once for a poll question.
Assume models.py to be as follows,
class PollUser(models.Model):
username = models.CharField(max_length=120, unique=True)
class PollQuestion(models.Model):
question = models.CharField(max_length=250)
issuing_user = models.ForeignKey(PollUser, on_delete=models.CASCADE)
class PollChoice(models.Model):
text = models.CharField(max_length=250)
votes = models.PositiveIntegerField(default=0)
Is there a way to implement this functionality, without making this check in the views?
I have a django model that looks something like
class Person(models.Model):
name = models.CharField(max_length=100)
favorite_color = models.CharField(max_length=100)
favorite_candy = models.CharField(max_length=100)
and I want to make a template model for it. Basically, I want a model that can have an arbitrary amount of Person's fields filled out. For instance, say I wanted to have a template for Person that likes chocolate - I'd say something like chocolate_template = PersonTemplate(favorite_color='chocolate') and if I wanted someone whose name is Gerald, I could say gerald_template = PersonTemplate(name='Gerald'). The thought is that I could use these template objects to later pre-fill a Person creation form.
My main question is an implementation question. It's totally possible for me to make a template like so
class PersonTemplate(models.Model):
name = models.CharField(max_length=100, blank=True)
favorite_color = models.CharField(max_length=100, blank=True)
favorite_candy = models.CharField(max_length=100, blank=True)
but the code is horrible in that I have to manually copy-paste the contents of the Person class. This means that if I change Person, I have to remember to update PersonTemplate. I was wondering if there's a prettier way to make a 'child' of a model where all of the fields are optional. Setting all of the fields of Person to blank=True and adding an isTemplate field is also a no-no because Person and PersonTemplate should be two different entities in the database. Any thoughts on this?
Yes of course :)
class PersonTemplate(Person):
field = models.CharField(max_length=100, blank=True)
Its mean you have every fields from Person and you can add more specific fields for PersonTemplate
class Person(models.Model):
Already extend from Model, its why you have access to created, modified, id, pk....
What is good its PersonTemplate 'extend' Person who 'extend' Model.
Since Django 1.10 you can overrride field like that :
class PersonTemplate(Person):
favorite_color = models.CharField(max_length=100, blank=True)
favorite_candy = models.CharField(max_length=100, blank=True)