(Django) Limited ForeignKey choices by Current User

2024/10/12 20:27:06

Update

Thanks to Michael I was able to get this to work perfectly in my CreateView, but not in the UpdateView. When I try to set a form_class it spits out an improperly configured error.

How can I go about filtering the ForeignKey in the updateview?

End Update

I have a feeling I'm missing something small here but I've been working on it for a while and can't figure it out.

I have an app called story universe where the user creates one with a name and description.

I then have a character creator class where the user can create a character within that universe. This all works fine, except when the user goes to create their character they see a list of all universes created by all users.

Then there are other apps that will also mimic what I'm trying to do with the character creator.

I need to limit the Story Universes to only those created by the currently logged in user.

I've tried a few different ways and had the most success with the following, but with this code, no Universe appears when trying to create a new character.

models.py:

class Universe(models.Model):user = models.ForeignKey(User,related_name='universe',on_delete=models.CASCADE)name = models.CharField(max_length=100, unique=True)description = models.TextField(max_length=2000,blank=True,default="")    def __str__(self):return self.namedef get_absolute_url(self):return reverse('universe:singleuniverse',kwargs={'pk': self.pk})class Meta:ordering = ['name']unique_together = ['user','name']class Character(models.Model):user = models.ForeignKey(User,related_name='characters',on_delete=models.CASCADE)universe = models.ForeignKey("story_universe.Universe", on_delete=models.CASCADE)name = models.CharField(max_length=255,unique=True)def __str__(self):return self.namedef get_absolute_url(self):return reverse('character_developer:singlecharacter',kwargs={'pk': self.pk})class Meta():ordering = ['name']unique_together=['user','name']

views.py:

class CreateCharacter(LoginRequiredMixin,generic.CreateView):template_name ='character_developer/character_create.html'form_class = CreateFormdef get_form_kwargs(self):kwargs = super(CreateCharacter,self).get_form_kwargs()kwargs['user'] = self.request.userreturn kwargsdef form_valid(self,form):self.object = form.save(commit=False)self.object.user = self.request.userself.object.savereturn super().form_valid(form)

forms.py:

class CreateForm(forms.ModelForm):def __init__(self,*args,**kwargs):user = kwargs.pop('user')super(CreateForm,self).__init__(*args,**kwargs)self.fields['universe'].queryset = Character.objects.filter(user=user)class Meta:model = Characterfields = ('universe','name')
Answer

You need to make a slight change to the CreateForm class in your forms.py:

class CreateForm(forms.ModelForm):def __init__(self,*args,**kwargs):user = kwargs.pop('user')super(CreateForm,self).__init__(*args,**kwargs)self.fields['universe'].queryset = Universe.objects.filter(user=user)class Meta:model = Characterfields = ('universe','name')

That will then pull through the returned Universe objects into the universe field, but only for the currently logged in user.

https://en.xdnf.cn/q/118162.html

Related Q&A

Parse a custom text file in Python

I have a text to be parsed, this is a concise form of the text.apple {type=fruitvarieties {color=redorigin=usa} }the output should be as shown belowapple.type=fruit apple.varieties.color=red apple.vari…

Logs Dont Overwrite

Im using Pythons logging.config module to configure and use a logging tool in my project.I want my log files to overwrite each time (not append), so I set my YAML configuration file like this:# logging…

How to upload local files to Firebase storage from Jupyter Notebook using Python

Since I guess importing google.cloud.storage might be a very first step to set API connecting the firebase storage, what I did first is to install google-cloud on Ubuntu like this:$ pip install --upgra…

How can scrapy crawl more urls?

as we see:def parse(self, response):hxs = HtmlXPathSelector(response)sites = hxs.select(//ul/li)items = []for site in sites:item = Website()item[name] = site.select(a/text()).extract()item[url] = site.…

Pyplot - shift position of y-axis ticks and its data

Using pyplot, how do I modify my plot to change the vertical position of my yticks? E.g. in my plot above, I want to move Promoter down and CDS up (along with their lines in the plot).For the above pl…

How to exit a Python program or loop via keybind or macro? Keyboardinterrupt not working

I am trying to complete a simple GUI automation program that merely opens a web page and then clicks on a specific spot on the page every 0.2 seconds until I tell it to stop. I want my code to run and …

SKlearn prediction on test dataset with different shape from training dataset shape

Im new to ML and would be grateful for any assistance provided. Ive run a linear regression prediction using test set A and training set A. I saved the linear regression model and would now like to use…

How to eliminate suspicious barcode (like 123456) data [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.Want to improve this question? Update the question so it focuses on one problem only by editing this post.Closed 6…

how to get href link from onclick function in python

I want to get href link of website form onclick function Here is html code in which onclick function call a website <div class="fl"><span class="taLnk" onclick="ta.tr…

Python tkinters entry.get() does not work, how can I fix it? [duplicate]

This question already has answers here:Why is Tkinter Entrys get function returning nothing?(6 answers)Closed 7 years ago.I am building a simple program for university. We have to convert our code to …