this is my models.py
from django.db import models
from django.urls import reverse
from django.contrib.auth.models import User
from userprofiles.models import UserProfile
# Create your models here.
import os
class Category (models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Image(models.Model):
owner = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
in_gallery = models.ManyToManyField(Gallery)
title = models.CharField(max_length=100)
def __str__(self):
return self.title
class Gallery(models.Model):
name = models.CharField(max_length=100)
have_images = models.ManyToManyField(Image)
def __str__(self):
return self.name
class ImageInGallery (models.Model):
image = models.ForeignKey(Image)
gallery = models.ForeignKey(Gallery)
line 22, in Image in_gallery = models.ManyToManyField(Gallery)
NameError: name 'Gallery' is not defined
I want to have manytomany relation for Image and Gallery and class ImageInGallery to store the Image~Gallery relation sets.
also, I want images belonging to a certain gallery accessible from a gallery and vice versa, so I put both models.ManyToManyField(Gallery) and models.ManyToManyField(Image) in both classes
whats the reason of the error:
line 22, in Image in_gallery = models.ManyToManyField(Gallery)
NameError: name 'Gallery' is not defined
Place the Gallery model above Image
Ex:
from django.db import models
from django.urls import reverse
from django.contrib.auth.models import User
from userprofiles.models import UserProfile
# Create your models here.
import os
class Category (models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Gallery(models.Model):
name = models.CharField(max_length=100)
have_images = models.ManyToManyField(Image)
def __str__(self):
return self.name
class Image(models.Model):
owner = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
in_gallery = models.ManyToManyField(Gallery)
title = models.CharField(max_length=100)
def __str__(self):
return self.title
class ImageInGallery (models.Model):
image = models.ForeignKey(Image)
gallery = models.ForeignKey(Gallery)
You have duplicated relationship between Image and Gallery.
class Image(models.Model):
in_gallery = models.ManyToManyField(Gallery)
class Gallery(models.Model):
have_images = models.ManyToManyField(Image)
You only need to define one of those fields and then you can use it like the docs describe it.
If you remove the field Gallery.have_images then you can have:
# list all galleries a image is part of
image_instance.in_gallery.all()
# list all images from a gallery
gallery_instance.image_set.all()
Just keep your structure the way you want, and put the model name inside quote
Like:
have_images = models.ManyToManyField("Image")
if the models is in another app, use the name of the app
Ex.
have_images = models.ManyToManyField("app_name.Image")
Related
I am trying to create a ModelForm for my Model Class "Asset" in Django 3
from django.db import models
from django.contrib.auth.models import User
from django.forms import ModelForm
class Manufacturer(models.Model):
name = models.CharField(max_length=100)
class Asset(models.Model):
serial = models.CharField(max_length=200)
manufacturer = models.ManyToManyField(Manufacturer)
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=200)
I managed to create a Form via the following code
from django import forms
from .models import Manufacturer
class AssetForm(forms.Form):
serial = forms.CharField(max_length=150)
manufacturer = forms.ModelChoiceField(queryset=Manufacturer.objects.all().values('name'))
name = forms.CharField(max_length=200)
description = forms.TextInput()
status = forms.CharField(max_length=200)
category = forms.CharField(max_length=200)
The querySet results in a dropdown being filled out with either "{'name':'Apple'}" or "('Apple',)" depending on using values or values_list respectively. How can I just display the name itself?
Adding the following method to the model fixes the problem:
def __str__(self):
return self.name
This will return the name and only the name to the queryset.
I am a beginner in Django. I am building a data model for a Django app, named PhoneReview. It will store reviews related to the latest mobile phone. It's table should include:
a. Brand – details on brand, such as, name, origin, manufacturing since, etc
b. Model – details on model, such as, model name, launch date, platform, etc
c. Review – review article on the mobile phone and date published, etc
d. Many-to-many relationship between Review and Model.
Here are my codes in models.py:
from django.db import models
from django.template.defaultfilters import slugify
# Create your models here.
class Brand(models.Model):
brandName = models.CharField(max_length=100)
origin = models.CharField(max_length=100)
manufacturingSince = models.CharField(max_length=50, default='null')
def __str__(self):
return self.brandName
class PhoneModel(models.Model):
modelName = models.CharField(max_length=100)
launchDate = models.CharField(max_length=100)
platform = models.CharField(max_length=100)
def __str__(self):
return self.modelName
class Review(models.Model):
model_name_many_to_many = models.ManyToManyField(PhoneModel)
reviewArticle = models.CharField(max_length=1000)
datePublished = models.DateField(auto_now=True)
slug = models.SlugField(max_length=150, default='null')
def __str__(self):
return self.reviewArticle
Are my codes correct? Am I in the right direction?
Don't use camelCase in model fields. Use snake_case. Second thing is, when you want field to be default 'null', just use null=True, blank=True(optional value).
I've also provided related_name to your ManyToManyField, so you can use PhoneModelInstance.reviews.all() to get your all reviews for this specific Phone model. For large fields containing text, use TextField.
Edit
I've also added foreign key in PhoneModel which points to the Brand.
from django.db import models
from django.template.defaultfilters import slugify
# Create your models here.
class Brand(models.Model):
brand_name = models.CharField(max_length=100)
origin = models.CharField(max_length=100)
manufacturing_since = models.TextField(null=True, blank=True)
def __str__(self):
return self.brand_name
class PhoneModel(models.Model):
brand_fk = models.ForeignKey(Brand)
model_name = models.CharField(max_length=100)
launch_date = models.CharField(max_length=100)
platform = models.CharField(max_length=100)
def __str__(self):
return self.model_name
class Review(models.Model):
phone_model = models.ManyToManyField(PhoneModel, related_name='reviews')
review_article = models.TextField()
date_published = models.DateField(auto_now=True)
slug = models.SlugField(max_length=150, null=True, blank=True)
def __str__(self):
return self.review_article
I want to define a relationship between Book and Member through Borrow in models.py
ER
But I don't know how to define the Borrow relationship.
In the Borrow table it must be determined which books have been borrowed by who and which books have been returned on which date. Should I use another table for this date field?
models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import gettext as _
class CategoryType(models.Model):
category_name = models.CharField(max_length=200)
def __str__(self):
return self.category_name
class Book(models.Model):
name = models.CharField(verbose_name="عنوان", max_length=128)
number_of_copy = models.IntegerField(default=0)
writer = models.CharField(max_length=64)
B_category = models.ForeignKey(CategoryType, on_delete=models.CASCADE)
class Meta:
ordering = ["B_category"]
def __str__(self):
return self.name
class Borrow(models.Model):
borrowed_from_date = models.DateField(_("borrow Date"), default=0)
borrowed_to_date = models.DateField(_("return Date"), default=3)
actual_return_date = models.DateField()
borrowed_by = models.ForeignKey(member, on_delete=models.CASCADE)
books = models.ManyToManyField(Book)
def __str__(self):
return self.id
class Member(AbstractUser):
pass
I think in the Member class I should have a field containing borrow_id, but how?
It seems to me that you need to use a ManyToMany relationship with a through model (this way you can store extra information for every row of the Borrow model)
...
class Borrow(models.Model):
borrowed_from_date = models.DateField(_("borrow Date"), default=0)
borrowed_to_date = models.DateField(_("return Date"), default=3)
actual_return_date = models.DateField()
borrowed_by = models.ForeignKey(Member, on_delete=models.CASCADE)
book = models.ForeignKey(Book)
def __str__(self):
return self.id
...
class Member(AbstractUser):
borrowed_books = models.ManyToManyField(Book, through='Borrow')
Maybe this link (https://docs.djangoproject.com/es/2.1/ref/models/fields/#django.db.models.ManyToManyField.through) could clarify it more.
I'm trying to write a BookApp. Every time I create a new book, it's going to load chapter field from previous a book in the selection. How can I remove the relationship away but not deleting the content. I have also included pics.
#models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=250)
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=250)
def __str__(self):
return self.name
class Chapter(models.Model):
name = models.CharField(max_length=500)
content = models.TextField()
def __str__(self):
return self.name
class Book(models.Model):
category = models.ForeignKey(Category)
name = models.CharField(max_length=500)
summary = models.TextField()
author = models.ForeignKey(Author)
chapter = models.ForeignKey(Chapter)
def __str__(self):
return self.name`
And in the admin.py
from django.contrib import admin
from books.models import Category, Author, Chapter, Book
class BookAdmin(admin.ModelAdmin):
list_display = ('category', 'name', 'author', 'chapter')
admin.site.register(Category)
admin.site.register(Author)
admin.site.register(Chapter)
admin.site.register(Book, BookAdmin)
Here's the imag of problem.
Added Book#1
Chapter of Book 1 still exist in loading
You have the foreign key relationship between Book and Chapter backwards: Chapter should have a foreign key to Book, not the other way around.
I need two Django models: first with Users, second with Projects.
Between them I need many-to-many relationship with an additional field(s).
How to make the below code working?
from django.db import models
class User(models.Model):
name = models.CharField('Name', max_length=50)
projects = models.ManyToManyField(Project, through='UserProjects')
def __str__(self):
return self.name
class Project(models.Model):
name = models.CharField('Name', max_length=50)
users = models.ManyToManyField(User, through='UserProjects')
def __str__(self):
return self.name
class UserProjects(models.Model):
user = models.ForeignKey(User)
project = models.ForeignKey(Project)
is_active = models.BooleanField('Active')
At the end User.projects should return Projects for specified User
and in the same way Project.users should return Users for specified Project.
There's no need to put the m2m field on both sides
Jussi pick one, and Django will automatically create a reverse relationship for the other direction.
from django.db import models
class User(models.Model):
name = models.CharField('Name', max_length=50)
def __str__(self):
return self.name
class Project(models.Model):
name = models.CharField('Name', max_length=50)
users = models.ManyToManyField(User, through='UserProjects', related_name='projects')
def __str__(self):
return self.name
class UserProjects(models.Model):
user = models.ForeignKey(User)
project = models.ForeignKey(Project)
is_active = models.BooleanField('Active')
Here is the simplest solution in my opinion:
from django.db import models
class User(models.Model):
name = models.CharField('Name', max_length=50)
class Project(models.Model):
name = models.CharField('Name', max_length=50)
class UserProjects(models.Model):
user = models.ForeignKey(User, related_name='projects')
project = models.ForeignKey(Project, related_name='users')
is_active = models.BooleanField('Active')
In above User.projects returns Projects for specified User and also Project.users returns Users for specified Project.