简体   繁体   中英

Failure to save certain attributes from ModelForm to django database (Logic error)

I have a ModelForm called ListingForm . It takes data from a user but I have stopped some of the model attributes from appearing in this form as I want to feed data to those myself. I have put print statements in my createlisting function in views.py to inspect if the data is actually being saved correctltly, it turns out the data is being saved. Here is the createlisting function:

def create_listing(request):
    if request.method == 'POST':
        import datetime
        listing_form = ListingForm(request.POST, request.FILES)
        if listing_form.is_valid():
            bid = listing_form.cleaned_data['starting_bid']
            print(bid)
            listing_form.save(commit=False)
            listing_form.user = request.user
            print(listing_form.user)
            listing_form.date_made = datetime.datetime.today()
            listing_form.is_active = True
            listing_form.category = Category.objects.get(name=listing_form.cleaned_data['listing_category'])
            print(listing_form.category)
            #The form is being saved correctly here, and the print statements give the correct results in my terminal
            listing_form.save()
            Bid.objects.create(user= request.user, value=bid, listing=listing_form.instance)
            all_listings = Listing.objects.all()
            return render(request, 'auctions/index.html', {
                'all_listings': all_listings })
        
    else:
        listing_form = ListingForm()
        return render(request, 'auctions/createlisting.html',{
        'listing_form':listing_form
    })

However, when I try to access the data from the model Listing from which the ListingForm is inheriting, the print statements I have put for debugging return the default values for certain fields (category and user) instead of the values I have saved in the ListingForm . Here is the code that allows me to view the data for the model instance I have created. Mind you, all the other fields have saved correctly except for the fields category and user :

def view_listing(request, listing_id):
    listing = Listing.objects.get(pk=listing_id)
    #the print results return the default values for the fields category and user instead of the values I saved in my ModelForm
    print(listing.category)
    print(listing.user)

    if request.user == listing.user:
        return render(request, 'auctions/view_listing.html', {
             'listing': listing,
             'flag':True,
             'count': listing.bids.all().count()
        
        })
    else:
        return render(request, 'auctions/view_listing.html',{
           'listing':listing,
           'count': listing.bids.all().count() 
        })

What could be the problem with my code?

Also, let me provide the code for some of my models and a form as the error might be embedded in those:

Listing Model :

class Listing(models.Model):
    NAME_CHOICES = [ 
        ('Fashion', 'Fashion'),
        ('Toys','Toys'),
        ('Electronics','Electronics'),
        ('Home', 'Home'),
        ('Other', 'Other')
    ]
    
    title = models.CharField(max_length= 64)
    date_made = models.DateTimeField(auto_now_add=True)
    description = models.TextField()
    user = models.ForeignKey(User, to_field='username', on_delete=models.CASCADE, related_name='user_listings', null=True)
    starting_bid = models.DecimalField(decimal_places=2, max_digits=264, default=10.00)
    upload_image = models.ImageField(blank=True, upload_to='media/media')
    category = models.ForeignKey(Category, on_delete=models.CASCADE, to_field='name', related_name='category_listings', default=NAME_CHOICES[4][0], db_constraint=False)
    listing_category = models.CharField(max_length=12, choices=NAME_CHOICES, null=True, default=NAME_CHOICES[4][0])
    is_active = models.BooleanField(default=True)
    watchlist = models.ForeignKey('Watchlist', on_delete=models.DO_NOTHING, related_name='listings', null=True)

Category Model :

class Category(models.Model):
    NAME_CHOICES = [ 
        ('Fashion', 'Fashion'),
        ('Toys','Toys'),
        ('Electronics','Electronics'),
        ('Home', 'Home'),
        ('Other', 'Other')
    ]

    name = models.CharField(max_length=12, choices= NAME_CHOICES, unique=True)

User Model :

class User(AbstractUser):
    def __str__(self):
        return f'{self.username} '

ListingForm`` ( ModelForm```):

class ListingForm(ModelForm):
    class Meta:
        model = Listing
        exclude = [
            'date_made',
            'user',
            'category',
            'is_active',
            'watchlist'
        ]

Any form of help would be greatly appreciated.

When you call listing_form.save(commit=False) it returns an unsaved model instance with the submitted values. If you assign that to a variable, you can use it to set the other field values and save:

def create_listing(request):
    if request.method == 'POST':
        import datetime
        listing_form = ListingForm(request.POST, request.FILES)
        if listing_form.is_valid():
            bid = listing_form.cleaned_data['starting_bid']
            listing = listing_form.save(commit=False)
            listing.user = request.user
            listing.date_made = datetime.datetime.today()
            listing.is_active = True
            listing.category = Category.objects.get(name=listing_form.cleaned_data['listing_category'])
            listing.save()
            Bid.objects.create(user=request.user, value=bid, listing=listing)
            # You should probably use HttpResponseRedirect to an `all_listings` page, rather than displaying them here
            all_listings = Listing.objects.all()
            return render(request, 'auctions/index.html', {
                'all_listings': all_listings })

Here's a link to the ModelForm.save() docs .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM