I want to do a many to many relation in Django and display a list of variables in the admin panel.
I found the documentation a little bit complicated to understand and I am unable to make this work.
This are my files:
models.py
class LanguageFramework(models.Model):
name = models.CharField(max_length=200,blank=False, null=False)
def __str__(self):
return(str(self.name))
class Project(models.Model):
name = models.CharField(max_length=200, blank=False, null=False)
languages_frameworks = models.ManyToManyField(LanguageFramework)
description = models.TextField(max_length=10000, blank=False, null=False)
github_link = models.CharField(max_length=400, blank=False, null=False)
post_link = models.CharField(max_length=400, blank=False, null=False)
class ProjectsGotFrameworks(models.Model):
project_id = models.ForeignKey(Project, on_delete=models.CASCADE,default=None)
language_framework_id = models.ForeignKey(LanguageFramework, on_delete=models.CASCADE,default=None)
admin.py
class ProjectAdmin(admin.ModelAdmin):
search_fields = ['name','languages_frameworks']
list_display = ('name','languages_frameworks')
filter_horizontal = ('languages_frameworks')
fieldsets = [
('Project info',{'fields': ['name','description']}),
('External',{'fields': ['github_link','post_link']}),
]
So what I want, is to display a list of all LanguagesFrameworks elements in the ProjectAdmin page and let me select which ones of the list are in one project.
Thank you in advance.
Related
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 = False
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!
Rename ingredients to some other name in FullRecipeSerializer. It conflicts with ingredients in Recipe model. This should solve your issue. For example
class FullRecipeSerializer(serializers.ModelSerializer):
ingredients_recipe = IngredientsSerializer(many=True, source= 'ingredientid')
class Meta:
model = Recipe
fields = ['title','ingredients_recipe']
I am a bit stumped as to how I can add multiple access_token and items_ids in Django Admin. The models and apps involved are as follows. This is my first post so please forgive if it isn't in proper format.
Trans/models.py
class Exchange(models.Model):
created = models.DateTimeField()
owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='token', on_delete=models.CASCADE)
access_token = models.CharField(max_length=300, blank=True, default='')
item_id = models.CharField(max_length=300, blank=True, default='')
request_id = models.CharField(max_length=300, blank=True, default='')
class Meta:
ordering = ('item_id',)
I have setup a userprofile section for the admin:
Users/models.py
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True, verbose_name='user', related_name='profile', on_delete=models.CASCADE)
avatar_url = models.CharField(max_length=256, blank=True, null=True)
dob = models.DateField(verbose_name="dob", blank=True, null=True)
public_token = models.CharField(max_length=100, blank=True, null=True, verbose_name='public_token')
access_token = models.CharField(max_length=100, blank=True, null=True, verbose_name='access_token')
item_id = models.CharField(max_length=100, blank=True, null=True, verbose_name='item_ID')
just_signed_up = models.BooleanField(default=True)
def __str__(self):
return force_text(self.user)
class Meta():
db_table = 'user_profile'
users/forms.py
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('user', 'public_token', 'access_token', 'item_id',)
users/admin.py
class UserProfileAdmin(admin.ModelAdmin):
search_fields = ('user', 'dob', 'public_token', 'access_token', 'item_id',)
ordering = ('user',)
list_select_related = ('user',)
admin.site.register(UserProfile, UserProfileAdmin)
class UserProfileAdminInline(admin.TabularInline):
model = UserProfile
I'm really just stumped as I tried making many to many field but couldnt seem to link correctly and or the process broke when testing in a sandbox environment. Any help would be greatly appreciated! In my case I need to record multiple access_tokens and item_ids for each user.
It's a little bit confusing what you are asking...particularly the way that your data model is setup....but I'm going to make a couple of assumptions in my answer (it would be helpful to better understand what you are trying to do at a high level).
I think what you are wanting to do is to be able to configure multiple Exchange objects per user profile...in which case I would set things up this way:
1. The related_name field on the FK to the user profile in the exchange model will be how you access multiple exchanges...so in this case you probably want a pluralized name.
2. To be able to edit multiple in the Django Admin you will need to setup an InlineAdmin object.
3. The CharFields that are actually ON the UserProfile will only ever be single fields...if you want multiple then you need to move them to another related object (like the Exchange model).
4. I don't think what you want here is a ManyToMany as that would imply user's would be sharing these tokens and item ids (or Exchanges?)...but maybe that is what you want...in which case you should change the ForeignKey to UserProfile from the Exchange model to a ManyToManyField. The rest of this post assumes you don't want that.
trans/models.py
from django.db import models
from django.conf import settings
class Exchange(models.Model):
class Meta:
ordering = ('item_id', )
created = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='exchanges', on_delete=models.CASCADE)
access_token = models.CharField(max_length=300, blank=True)
item_id = models.CharField(max_length=300, blank=True)
request_id = models.CharField(max_length=300, blank=True)
users/models.py
from django.db import models
from django.conf import settings
class UserProfile(models.Model):
class Meta:
db_table = 'user_profile'
user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True, verbose_name='user', related_name='profile', on_delete=models.CASCADE)
avatar_url = models.CharField(max_length=256, blank=True)
dob = models.DateField(verbose_name="dob", blank=True, null=True)
public_token = models.CharField(max_length=100, blank=True, null=True)
access_token = models.CharField(max_length=100, blank=True, null=True)
item_id = models.CharField(max_length=100, blank=True, null=True)
just_signed_up = models.BooleanField(default=True)
def __str__(self):
return force_text(self.user)
users/admin.py
from django.contrib import admin
from trans.models import Exchange
from users.models import UserProfile
class ExchangeAdminInline(admin.TabularInline):
model = Exchange
class UserProfileAdmin(admin.ModelAdmin):
inlines = (ExchangeAdminInline, )
search_fields = ('user', 'dob', 'public_token', 'access_token', 'item_id', )
ordering = ('user', )
list_select_related = ('user', )
admin.site.register(UserProfile, UserProfileAdmin)
There is a lot that you can do to configure the inlines to behave how you want...but that's the basics.
class Venue(
RandomIDMixin,
TimeStampedModelMixin,
models.Model
):
# Venue model for storing metadata about a place.
VENUE_TYPES = (
('shul', 'Shul'),
('hall', 'Hall'),
('residence', 'Residence'),
('other', 'Other'),
)
address1 = models.CharField(max_length=256, blank=True, default="")
address2 = models.CharField(max_length=256, blank=True, default="")
city = models.CharField(max_length=256)
country = models.ForeignKey('countries.Country', null=True)
description = models.TextField(blank=True, default="")
display_address = models.CharField(max_length=256, blank=True, default="")
image = models.FileField(
blank=True, null=True,
upload_to=prefix_venue_images, default='{}{}'.format(settings.MEDIA_URL, settings.VENUE_DEFAULT_IMAGE))
name = models.CharField(max_length=128)
postal_code = models.CharField(max_length=12, blank=True, default="")
region = models.CharField(max_length=128, blank=True, default="")
venue_type = models.CharField(max_length=128, choices=VENUE_TYPES, default='hall')
website_url = models.URLField(max_length=512, blank=True, default="")
class Meta:
unique_together = ('name', 'address1', 'city')
def __str__(self):
return '{0}, {1}, {2}'.format(self.name, self.city, self.region)
I want to show above information in table format on admin site. I am a beginner having zero knowledge of django.
To show this model on django admin as tabular format you need to edit your admin.py file:
from django.contrib import admin
from .models import Venue
class VenueAdmin(admin.ModelAdmin):
list_display = ('name', 'city', 'region')
admin.site.register(Venue, VenueAdmin)
Assuming I'm understanding correctly, all you have to do is go to your admin.py in your Django app and add the following lines:
from path.to.models import Venue
admin.site.register(Venue)
I suggest you follow the django tutorial, and start at the beginning:
https://docs.djangoproject.com/en/2.0/intro/tutorial01/
I have next models in my Django project:
class Category(MPTTModel):
title_of_category = models.CharField(max_length=50, unique=True, verbose_name='Subcategory', default='')
parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True,
default='',
verbose_name='Category')
class Product(models.Model):
category = models.ForeignKey(Category, verbose_name='Category', default='')
title = models.CharField(max_length=200, verbose_name='Title of product', default='')
Also admin:
class CategoryAdmin(DjangoMpttAdmin):
list_display = ('title_of_category',)
list_filter = ('title_of_category',)
admin.site.register(Category, CategoryAdmin)
#admin.register(Product)
class ProductsAdmin(admin.ModelAdmin):
list_display = ('title', )
I would like to show in my admin panel only child category(category without children) in ForeignKey.
How can I filter category in admin?
I'm not sure if I understand what you are asking but check out this post as it may help.
Changing name of Foreign Key items at admin page in Django
I want to be able to edit all data on one page. How can i achieve this ? Should i modify my models? If so, then how should i modify them?
class TextStyle(models.Model):
color = models.CharField(_("color"), max_length=7)
style = models.CharField(_("style"), max_length=30)
typeface = models.CharField(_("typeface"), max_length=100)
class GenericText(models.Model):
text = models.TextField(_("text"))
lines = models.IntegerField(_("number of lines"))
style = models.ForeignKey(TextStyle, verbose_name=_('text style'), blank=False)
class ExpirationDate(models.Model):
date = models.DateField(_("date"))
style = models.ForeignKey(TextStyle, verbose_name=_('text style'), blank=False)
class Coupon(models.Model):
name = models.CharField(_("name"), max_length=100)
slug = AutoSlugField(populate_from="title")
background = models.ImageField(upload_to="userbackgrounds")
layout = models.ForeignKey(Layout, verbose_name=("layout"), blank=False)
logo = models.ImageField(upload_to="logos")
title = models.OneToOneField(GenericText, verbose_name=("title"), blank=False, related_name="coupon_by_title")
body = models.OneToOneField(GenericText, verbose_name=("body"), blank=False, related_name="coupon_by_body")
disclaimer = models.OneToOneField(GenericText, verbose_name=("disclaimer"), blank=False, related_name="coupon_by_disclaimer")
promo_code = models.OneToOneField(GenericText, verbose_name=("promo code"), blank=False, related_name="coupon_by_promo")
bar_code = models.OneToOneField(BarCode, verbose_name=("barcode"), blank=False, related_name="coupon_by_barcode")
expiration = models.OneToOneField(ExpirationDate, verbose_name=("expiration date"), blank=False, related_name="coupon_by_expiration")
is_template = models.BooleanField( verbose_name=("is a template"), )
category = models.ForeignKey(Category, verbose_name=("category"), blank=True,null=True, related_name="coupons")
user = models.ForeignKey(User, verbose_name=("user"), blank=False)
You need to create an inline model in your admin.py. See: InlineModelAdmin.
I have created a module for inline editting of OneToOne relationships which i called ReverseModelAdmin. You can find it here.
You could use it on your Coupon entity to get all OneToOne relationships inlined like this:
class CouponAdmin(ReverseModelAdmin):
inline_type = 'tabular'
admin.site.register(Coupon, CouponAdmin)
Caveat emptor. I had to hack into lots of internals to make it work, so the solution is brittle and can break easily.